From 978498fb32b9fb439bafebb188d7dc0a95f05abb Mon Sep 17 00:00:00 2001 From: OliE Date: Sat, 13 Dec 2014 17:42:28 +0100 Subject: [PATCH] add AndroidStudio project structure. --- android_app/app/app.iml | 92 ++++++ android_app/app/build.gradle | 25 ++ .../app/libs/hellocharts-library-1.2.jar | Bin 0 -> 145393 bytes android_app/app/src/main/AndroidManifest.xml | 32 +++ .../core/BluetoothCommunication.java | 105 +++++++ .../core/BluetoothConnectedThread.java | 83 ++++++ .../com/health/openscale/core/OpenScale.java | 262 ++++++++++++++++++ .../com/health/openscale/core/ScaleData.java | 36 +++ .../health/openscale/core/ScaleDatabase.java | 160 +++++++++++ .../openscale/gui/FragmentUpdateListener.java | 25 ++ .../health/openscale/gui/GraphFragment.java | 119 ++++++++ .../health/openscale/gui/MainActivity.java | 205 ++++++++++++++ .../openscale/gui/NewEntryActivity.java | 198 +++++++++++++ .../openscale/gui/OverviewFragment.java | 124 +++++++++ .../openscale/gui/SettingsActivity.java | 114 ++++++++ .../health/openscale/gui/TableFragment.java | 224 +++++++++++++++ .../src/main/res/drawable/flat_selector.xml | 5 + .../app/src/main/res/drawable/ic_launcher.png | Bin 0 -> 17493 bytes .../app/src/main/res/drawable/rect_normal.xml | 11 + .../src/main/res/drawable/rect_pressed.xml | 6 + .../app/src/main/res/layout/activity_main.xml | 6 + .../src/main/res/layout/activity_newentry.xml | 189 +++++++++++++ .../src/main/res/layout/fragment_graph.xml | 25 ++ .../src/main/res/layout/fragment_overview.xml | 122 ++++++++ .../src/main/res/layout/fragment_table.xml | 111 ++++++++ android_app/app/src/main/res/menu/main.xml | 12 + .../app/src/main/res/values-v14/styles.xml | 12 + .../app/src/main/res/values/colors.xml | 5 + .../app/src/main/res/values/dimens.xml | 9 + .../app/src/main/res/values/strings.xml | 10 + .../app/src/main/res/values/styles.xml | 20 ++ .../app/src/main/res/xml/preferences.xml | 9 + android_app/build.gradle | 15 + android_app/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 49896 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + android_app/gradlew | 164 +++++++++++ android_app/gradlew.bat | 90 ++++++ android_app/openScale.iml | 21 ++ android_app/settings.gradle | 1 + 39 files changed, 2653 insertions(+) create mode 100644 android_app/app/app.iml create mode 100644 android_app/app/build.gradle create mode 100644 android_app/app/libs/hellocharts-library-1.2.jar create mode 100644 android_app/app/src/main/AndroidManifest.xml create mode 100644 android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/BluetoothConnectedThread.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/OpenScale.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/ScaleData.java create mode 100644 android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/NewEntryActivity.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java create mode 100644 android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java create mode 100644 android_app/app/src/main/res/drawable/flat_selector.xml create mode 100644 android_app/app/src/main/res/drawable/ic_launcher.png create mode 100644 android_app/app/src/main/res/drawable/rect_normal.xml create mode 100644 android_app/app/src/main/res/drawable/rect_pressed.xml create mode 100644 android_app/app/src/main/res/layout/activity_main.xml create mode 100644 android_app/app/src/main/res/layout/activity_newentry.xml create mode 100644 android_app/app/src/main/res/layout/fragment_graph.xml create mode 100644 android_app/app/src/main/res/layout/fragment_overview.xml create mode 100644 android_app/app/src/main/res/layout/fragment_table.xml create mode 100644 android_app/app/src/main/res/menu/main.xml create mode 100644 android_app/app/src/main/res/values-v14/styles.xml create mode 100644 android_app/app/src/main/res/values/colors.xml create mode 100644 android_app/app/src/main/res/values/dimens.xml create mode 100644 android_app/app/src/main/res/values/strings.xml create mode 100644 android_app/app/src/main/res/values/styles.xml create mode 100644 android_app/app/src/main/res/xml/preferences.xml create mode 100644 android_app/build.gradle create mode 100644 android_app/gradle/wrapper/gradle-wrapper.jar create mode 100644 android_app/gradle/wrapper/gradle-wrapper.properties create mode 100755 android_app/gradlew create mode 100644 android_app/gradlew.bat create mode 100644 android_app/openScale.iml create mode 100644 android_app/settings.gradle diff --git a/android_app/app/app.iml b/android_app/app/app.iml new file mode 100644 index 00000000..f5aa27d0 --- /dev/null +++ b/android_app/app/app.iml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android_app/app/build.gradle b/android_app/app/build.gradle new file mode 100644 index 00000000..0b068ef2 --- /dev/null +++ b/android_app/app/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "com.health.openscale" + minSdkVersion 14 + targetSdkVersion 21 + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } +} + +dependencies { + compile 'com.android.support:support-v4:21.0.3' + compile 'com.android.support:appcompat-v7:20.0.0' + compile files('libs/hellocharts-library-1.2.jar') +} diff --git a/android_app/app/libs/hellocharts-library-1.2.jar b/android_app/app/libs/hellocharts-library-1.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..f73a0c99f2b3e5946922efd92013c0743dafe88a GIT binary patch literal 145393 zcmb@t1#D#7k}T>rwV9cjnVFfH?KU$rx3SF3%*@Qp%*@Q}HrxIC-1}zU`=fu3M)Q7Y zE!CDvRnpGf85t2POFgcJ$U3hVyiZ2Zx}NiC9_ zQ!NY=-|QF)T9y1fh{S)R4Vla2jx~#1W}AfbnQ9CdEZu?F6n=} zd+&JNJWm-jaV{TDZhrdYJbR>gom~Cye1!6oeR2A>Y;F$w{Zo0ay7ufM9SSg@_&X6% zda%Q@?JR0~k_=gl2#eZJSa_|G(abqGYSefo){g5`-n{hu0{?W4ox^i>fw_C5VaCbc z(0sH&5PMc(6FX`US&U?lwSO$P;Dk{iP&yQ!86=Eyy-9lj%+OGMHZxP|mI6x>lsK$Q z$o(o85ppo!G}nsBbW$$u%N?EGdO;zf&Tdjh#v^jI5Hrk*B8?Hvli8%zbZ}muK_rlf z6C-Lmo@#A}8uh}lkvLsK#Ed2JEuju$>^8mcb?sQE~Fl{vznzmX^SkpC7 z(Kjb8p*uR@iEC9?4TNr0Iz3hcEvxZEWZH5muOQVc<&+|>3l6u4g02@FmiA;I6xx>Z zk_lI}^mzM-%hK2`A=;Az+8#{y7;QNvGfk63lbY7qpaG>*R2&3r%q-B9q?MfW0D4#q z_6J94o*~0Id%qsB>Ai+57m_j=*f?p$Y#QqGpphg`ssiB>GBg&7=vBwikC2q5A0-74 zbl1O5TY>0IYt+T@-@-h&q^50BIy_9sYcA(!XS=1W8!GNkObR(lDjQQ-fxj^`Q5LKg zi4jG*uqrs{R07lpQji0-f_Tvw`O}JzbQ> zc40fKIMzUZcisd=AA>?B$!^sQ=|lDiJEe*F#4M3FpeD2Ch3;z& zu2|GyIC$s9eAVh_KFD^SPd2euL`yNdtgCu*It#-*6EUKPnaz1ztBls-h@fCGvJN>V z#i&hCKXG0hYXf7GdbBmTl|$!?nnBrR6H2BF#v^7dI&j?-99G6k7%MC@@_XJcI%sg* zj@0p+*?R!v$lsg)O&;gs{Y`u<-`x1s(@&}H^TQG;MCDGR{}%rqqe0CQ;dvR{P;H*p z&x_OOW}y!IIbxo%_kjMa74O+;(pz){W>hm+g-}(HI^S08+sPv2HS6&R=R7E)>uf>gV^EV%4`BQez?V>i#t%&iQ_8o*Eamo- z$(m+E=zE3X@CQRhc#PP4WDp|`D{1DnlHVsBMRa=kpm*cu%y{%ITY(6<-6ENojC_jd}J`pPy4~nU>d7Q zMf$-uo6B01Z2Dd#UA(quhIn)o`|#jS^LW3-DzaF2wgd07^f(jtvIOK(qks=yZ0NVC zR?H#>inPXvf=$((?Yi?S-5&3U`iPEzm3sOuS0vZ$6}s<_;Sa%1t|>=er7DvoX7d+1 z>%4!U;o$v*Yg-`5=*y;*{-yxw+cqSaH$Rgq?1x-oK__|<;C)KAPx0pk0QvPHMs zU@9%okkDq4rlN9M<%^^8Dg~P&%d;`Ub*v?&HFTRS%L`R$dI-xEWN=UHx#wV(H>$ja z(qFAPBcj(SbB(_}SW0H&ubYcHt`=RCpXX7y7PjczL=B*@Eex4ub<+A(chJdfi*DGM z;-lPR`<0Yd{UT<=>2&0NZ`hN1o_fVD*A(lvg9cccN9W9~>?1=RE*JwXG_P%?_Pai> zqqJ|C&2?9=&uL`gYiM7=&=`E5YP`Ed0xz{t++s-t?-Qc;$cu5mAcq6Dhjg8{3(^(( zq$?9DJK45v1udLX$=4+b_R0y8esN;%bB)v7d{ChO@%W?=F%)Sm3&OiiI+v-btO{+9rKAak+Xxe|Fm(t(bu^!hSRNrw$V{6^X z8H~Mf5NKuL&A|Iq1zor+9TT_&mkwddZHrI&fE3E;xXmHD0?K&3O|`e zE+@<+aRLJZp_|}HFf_nEp2s*oYXLLa-A1~zk&O0k9?l{RJtUD-FDQxhQ7bmtT%O{4 zmX!@$+}o)z`P{}N?hX*Uu9-t>ak*-XJZ;u+aFrv~*Dj?>={3-dsIU)h6I^mqVPMDV zkFi-b@rX@k`3)no)5t9H3N#=gWwk?NSCB+xlHXWEpWZHrP488@T8pJI9-iQmCo_f@bwNN+~;9PoWWKby6lWnL9K zeRQMRa*fz&?)|x(|Ld|w%W;8svE=Cz?w9%0B``SkHqz`_i6<(?Sv+|{A1%e9?J#Syo=Uc3 zWFtu|OH;DNvk6T}V2!1agCW7jRF=CaTJRP%;gsDYJQRO7Ou2 zXcej32l&;)j4LT6oi-;Z5pp3}5-}&gafnF4hO@dkQ))Jwl;?=Us3Z%f!R_?(mQJsS)VZoS@r zAbVHKyo44WCjokd7O8|5ZS1k(ET|Mgf{$nrf1&CXvAQ3hNn*>8cryTfEJWsf!dYAb zAqIhtZ_6fO10ryv2 zpL$DF@y2n*pM}kjWKs6AE;muLI|5~y;s6Ts zr+rsi)P++2QX5n?R`3OE#;$PquH$eKhi?Sl?oHuPGQ*E`wbS(_iiPU2-S$m1U0bLB zT%TXB!9&rRLEiev^;xbBP$gaiNPLr~`arMi(=gzfY%=6qJMsQM=03ZSBv>kXEmuxJ z?=Lb#64pYV|J)SzhZ-(inb41xJ=uN!&x|7$s4eV8J9JGn%T!w%dYp9#sU}4g^LK@c zD3etUvkeV$Umc5l7=@@x{q>(A$eciS{0U(0MC7|WCp?>3J}ubw#_X+KXCGuurxe>2D?w|X@S+glo-SSq4eg(y}JDb|oOLs->9 zS|RjEu~yik&EI=H#mpoADrg+b>NaB&QwnWgSb>g7SbMD(XsZwXwN8tf%(|BRsd)Ld z@blYW93Pi{4J`s12nYx3pEy4I-*S8r7aJRoe-V8_TMHWlXA3)984D+86I+x2;QI=) z(gOkrJ{!eR#dGV+__^%-y`o_B;RH$90eDnhcJo8lYnMXxv@Z=jka!>8z9<}&tSFFB z;F;}?8E>wpJAZa|f8!XajsYJiOO~{3Q)84bT4s|Jy@vATo~bV}(A>dDf-I>FQ`sww zYlDw5Fe5_?urk1V_2EefdzdqAEoDdELF?R(%kwFUbXsor-#TcGbbqA{35Co<DGx~xDbEJZzmw@sCd;bbm;Ubr#Dn*V z3&L~X*ga*WwLGV&0}(&cE<%uNf#*3i-ES#a+5{+&XrAjGDn4?k-fxqvk)YgVJ*uRS zX^^2|1y!|aK&U%yc0HXijnXtii1$42v%&MfBWRgXsjYG5@nOh8MunwGV!Kpw*UpkT z^Po;t@Z6g?QhU=v^3H$?$&2Pg^+2)JD-;FAJ?}^k2UUml)Mp?90#UPwj!XDUFwrwN zBF2evK43*_?PRh+@0CywpVbz)>0BdyZhc=^Urkw;J28{3F54=@Tpn&QpOn*FHJXzJ zt!tgBypVC1z1f_pZ!I)u>TU!&K%Y{^pfogity6wqCI0Hb|0@|kf0k%d{z-<|KPH3e zZ&-L;gp`7{n>KhCwsuw)win>L7ssuw9ngTvw3hGCQSCHBqH6PmZ;6TQIZA?_WYr_nuFSf%bd_%oVY#oFrCj!SL?wF{1$TG0 zc+|fzgs}8h6u^nF$Qq#a*0Qyy#%&+8K37Ytiecu}_lIpj9u0K{thf_nx8@SWJj2W- zUq}>~S>FYiD{!|h`6xx;emWsJDfWqTChj>d)SFYt>3AvjIwDBx)>xRyfKlJCA}(;) z)y#^lnr0mj#lspyRAtCkOg;$dHM*Zvuyj>5t3)a$>y45Nr0=|fTO^T=NxU(Ox7N#t ze2Q`1@O=1&0BPhUc#X4rt(X6J zg~BVMv_A}~$P|fJ&uerjtV0`C)-ETy0NsavRpyKZI8 z;T1XNL?k(xVK;GSQRMdA``&jx4|{OmDb5{+!>j0d3(~$xhf_*HnXkRfMk5WEX_}^) zLJ!<1U&7lspD97z-_U;*TeYSQ4lD=|kT>{0A>ZE@+aJ(#`#aR*{$;nq2M!KS3@+yi zP9_GPmAQBr>HV2GN%9%Fn3?%;7&(|9Z}?d|xp*J&k&ko|IoSEAk~6sVjMec+k!W$#U=(W25t(DpbyFwoa7HXXsG`^UIqr|U(TAIoFH4;9}L;}v;Q9Q zdHxn<4F03n{@Y{wo7QU+%?sDh02BOUTs{vuAP%}$hy>gJQ+__I-nGW6?{L=@ zk%y(zBN$m!JLOp-|Ag>XY&7t~Zcm4*Oo}toDQ&X2{~A11RZEtEn#$g~B~=x%|LgBs z)Dsx6c;wdlMBZM658-LvIK&H#o_|r0q_2F`f3t9DPZqR1d)n`4qpovh4BLGg zF-y0$Db_;{Dag^LiO3aTMYxnB$m;A(PYt)ZDR~ru&x`yP-1s#T5==r}xyVEg(|`EG zG^P;5t&x+xLuXX6m}KvqB1s!vqKhTG+$osPvNUCt;s z+sfm|^$`4DRcC|CJ`Vk-#pVCmfB*1t{dXU}|1;idj4c0ld9&0ul(5AScnheJtgiKY zSAoBC3XzQJ!>H8aPUx@cV*;-_GPKdo`=Lp9gu8+zoqPyw-+%KRlP(8_lccIC8-G6J zOv;|KY=SW0OqSv% zqpC_XKMuxgXsFS$Ql>;YntHN9;0v$#dzO+xm3QZ8?C|bt_Cqts{I=^PSjQk!vzLbWsY?ncQP z2VitE&`u;7-gO**4YWpnAz)NfoQkBR>Z;m9;u?rBpbb(87mB{1=!|@a5j3J#Wl)jc zG$Lo6V><0uRT1Py**g~oW0YZNtZ38WEoV29)u&T|0TUOHrFwzDk6<}+jH=hL27jRo zkN3ZkvEuqsf#T-zn%1tp3&U$cT!F@9sfoOEC7P48A~S#8A(@|dDuIAod?bhZZCI^B zy`xGW?g51~L3<*pzKd6GgLdF5#Jlb%=yZMnw-AT#Sy(ygiC>*6Kw3LF-RGAI?Hc;| zWVvTDI*u6dzJCDeH^kCw#a7rY#?oOq2CK0O&pL4^Jfq+|x10_1lQtF2DK*ZxZsjZY zfD*w%OfhZLumILd-3~%QT{oJ=y}L>H9=7P_D(w_~Jo& zbk^pna9az}?tFa9Vlhv-^L7JCfrrZ&VH?gmRm!CCO_s7v(Vk~~sG<19l^4bOLPiQ| zt~m{=(&Dixf^HLxZVhOZlVPzThS|;u{mAtElx<&7#QZtpH{v9l81pd}PmzRTMj6+w zMya!6yPbrtkm1)C?8l*>BS%;47+k~l-uD>94!`mJZS3BMo8{MDP*;~^%!8>^Bsl1qNGQRN?dV;w*;%cR3jYL!}=9yZY!7RDwPP3~8l#Y^K6 zJV&X(VWj{K+3ccq=NK87)lHAI1wycpr~~P zEK_DP&lFu$evdaVOslf^T&emg}w7hbuGkT3s z)j`);8;I_D>l)W|XF6TX^sEfhV7$O`O>CF5lTZW-Bli_-tM1=PCQ=@^*ADu9H^t(4 z4^i@#5zIFDi;&lW5!X2tZrrePLf%|2VG{0Eip(!hAZH&g6%rRfV+=o59pp$Lf*9Hh z6Z8f07f9A4C_i=mIsB^lqmBO_B)R`bAjv_(_`gt6|bD_5N&th33ZcYKw|`&7|flE!91+Zb}?gWPe9o<`RDk#LzMX$FBL8 z(Nup9VM|3C=moUt0FR1JimF}#ZsBKe&z3!od~0dIQ*QZ3+(DymUhpSbX)oAOseZfx z&z4fKOc-Id6Lmc@j5Y_1GYR4VTeMsuhM|S*s+vM{=UQn}ksJN|maaXmK}t}`V<+Tr z6DFXc3IY?8n3=I=kE9Oz6Z{Rs6{=*vt=zD^oAY@b-k4UrDVf972p+_45kxgX)MUd` z8HsBn%m;&^HfPTm8j1tl!H;n7`(vno@DYGhjAdQX!hKH)7VnTFh=o<~Rhgf9`b@Q6 z=;D}_bix5c93zq{t+r@nR{LdW`WHl&1kx{z5J)M3kXo9v5QEmaeND8lNDLbX;1ZZj zlD3~vyBtx>&fVFSZ4*r7)*UpJq?RYukETsbq*qZ~E^sGh%6Sxkyq-{9wR@97r+jF1 z28&&yf!&@~oD}C<*GlarvIi8$9x7_jcgkq$QAMCcWQm&V^>yBXQ_r6RTG(0XufbwM z)%)rGJOj5sXF02l0NW>EnAW`_`K2WfY2HZe3M>lxtL<}@`4Hte><$r3n#v-wg%5*E zxUB;Y=uR-aJsurDYC;9XNTne~)TQt@K%zt32WM5?KJ~TM_mki>c8bNBGtx>L5lgPE zl=@3n62h4r+k@*ZXi-JGUen1=HUVa1o%0FZvH{LADm_aCaSA)4eE&pkU9`X<-HIfQ_XCdS{hPMB(6nn*u>9jWp7TQJ zf<^)FDeN7t1Z#!2Xr}G%k@)3gbwG__O(zdR6kxkkR1Dteh5<`(?~ypVdqe{?Qy0WX zTP=U=$bV%jsV0k6rp4mix?2)Qci@WcgJvPZ>qgNtmvlsEOf&xb8;`@|+?G7-Y82yT zpXlWf$&(Qthz5Z(rf^=7pq6-jMlwfosDq!(lyW%!0VJ=Flsoq-yUeh~6OHw>Q)ljP z4hJB_=AhuJyo>LD74qV6{F?qBjZyHA8iVtHR>=RWj8%1&u~jjA;UKLcCe(9L%xP(V zz~}K#R9`tB})})xg=ChHD~COb@ZM6yj80C_||nNWER=Pbx_6pg;#@{RpTQpCZ$^had8`io16%QyC7-4=GWx-kSvD}>DX{h%HkolkezLLwGgQq}7;0A`=_`$ur zm0(Cc0v`ir*ruc?Syqz?1yg+Sox8rOrk`U1SZmwaDSC)u%OX2GJByiTXBDbQW!8qh zHasL7IRLZFl9HXgx5aAFd|C4|zWKA)(Ilvd87OPq_o|U}Ybcy_g_Sv))FGSUJ(s9R zY$5z=y^ji!Y$yA9wOhb>YeLgOWVWW@dkQGgSly>7L}x((rUNVpaD*92NAi?b;RsA6 z?8S?Uv;dC!EWHox`Kdq&V2@e4N0ACeZ*hh@I&XHu1sBrU0s}dfUz{IKek5+NRptS_ z!XAzP_qh@0p{bHMJKg9)A{=fNmg#Du9h)4^0^y?vu8ldmx%@`8OO48?#!!d>F0uu^ z71z7zT=EU70n6wHU)402Vy+D|c>5Tn(oWRk?gC zz!Sgg%yv4t4hu(QqAPCT~SS~l+h>^kVl4*c2+QHD6YP?1Z6Bj#`#FoBVI>KyBH;vsHg~iLKf8AWec36cm5dG?VhItFxFRz)^wcHp#0bq8eak}~v`G*oSo=Ato}M%4_X z7lE>0_E2`|j%o#YIh(XVA)gxbLrQn}|3WDKu8VB$KU6~%^8XjA@gJthf6>5-veH6= zD7@;j6Zgd0L7%{Z<^<+P=LQe~l!a~P#0L-Y#0N5+?CU?R=HO4oMIXQuDFWG?Os6xw zZqk_XbL?(_Z0*&AqU|d<^)&u)X&MbHY#;iGOt*qLcPv=X=ebsP9GM$D{C_-CyNq)ys?q zAoD&``tb8UsbEdVi96&Buc@YjBD&7>%=*xLOm8t?o5Da)c#}UULxfShU&JYh--C=Y zLI2o~wE)jjPT2Kf^uOYNx-%Mq{znU6|Dzt}`|oy${~G`Qt%=oN)s@9jz5vz;*-#FB zO}4oRiv;0H2&i+VDC!Khy55p_w=A70$6W$dRa@E{md~H~r}UpiClt%gB|V;Uze}@y znQ!7mU;xB8Om5ecpVyz)UChW|pEolA?5f`DI z&()gsGuFbVoGz-I`a{oJ0VcBqRJAu2fr;7FSn`^>qh>BEsST*5E1zKgQ^c$SZ(u^< zLA}Xw=ZD2(!v{lC(l{*vxxLL`k;Rvlanh4l1$#>CvKXkzQOS(T*{mu1)DNe+Kwf&y z-%qsXwO{-!(yj&lo1fMzxs-tW2*Ggz-VnL-5j08+NS71#h!6mzgY}3DOmgTY^I`@v z@+UC;Xuu!r_E5H>)c9+jgXCW#c+y^hSDHo zO;#EJGRh%V7O#0YSVk7nT4{YZm)e4%va*aNC%hp!c#jsqkp^KAFIKX?1q$yfejlHI z6swk^Fufj1=<2~(W>rVMt9k-1E4D`a`N}MWY&+JhJwnK;ZuA}=En4EYgatkwY>9Mu zOO61-^oup?HpGtg3JiL8_ceK>^Hcyy^u+YE=}FG)m!)3>=VrP3MFXj!VJf*a?wFD& z=rqk@-2>dwzN;i#6-Ut?%XIBds=9x)sOK${gWQ0}S_L601-z743zJwiO5LWDps>_6 zq?eUUhD{QiJ7=s(rKZTt0V=HeU48GLnTGB7I9asE$Q1nSG-D9XuJS!rorADR%mWx{ z3KK11F)EPitQ05Vf!53rsN=yxYSsiSnKH-{o0X;#V^`bJONLVkuXujkGBJ%&aeZj( zau+vqcihWRj0Y|i8Wfm{{qRV7rYUt}b(Yg3I0(*8H<&fb^^Sq?d%)JmD}vggd@~i$?ad$ zg>gRdeICSiquPaKLhMx73V_=E(BSN*cOHGHG5(G!3X@s+wED!(=d zwn!|sfN-Z1m>U1!`p(ia>_=pIuxjbaFnVGkn;|h<*-DQfCkm8p7yNUo0T}1`UC1iV zZ|JHNe8UY8Yx)RWle&a`x$v+*(CEe|;KuXl_Trd(w|SK7dJTW+bxOxJf$JsZF9ITTK4_IKC>_DXj+=YA*xTBDkGI2Tr)raU8T?& zm^_SzAu`2V$zuBGYstC0%L$DbhuhWNXoqGx*(i+iUOTN`O>9Bz!UpwAE#;$1jTK2M zUN!zp%;MyAqa+?`(d)(NK^n>Ih#R%~`0Bv{j4r;YAA$BV62j#fs}dIA(c$q!ia_R`!TKHkMZUpZ;O1=%hd{B|bns{W84J!4-k~LXP?<#yNNtvwk2jO!j zXjA?A4 z3N1`wdXw^g2AZn!_38vg*{vLiT!n#6g$=m>@tyR#%xBV5!FR zP?SEa17-lYZg$PHNVgnAfH7z(=MF=sG&aa#Yyf4-%V_tCGazcSOH_#?Ol=q^0tSHK zKyej7>>`MRG6DpYxNxXWi(A(#Q-Zn)0Y5pFufjE$5S2XN4b}cH|hwgZiRDf$4J^|gt4w1AcTIm#)5z5ZqTop=0 z;Z+#kU|dSs_jT(;of&&$0o=JV%XItB*};is-RE2j@yoA zNi!Q0JezTcJ!A^13=_-;x@0s?wL%ik-f?;}?WCFp;89NmAF3sjYFy<3r^c{7>l`BR z;djZ~?6ev;nsYldnTrOxsiMLy*1*~)q5b5Tzx^tcb}>&BehJlhJ>oH^-Uw@ZeES(x zhXH0h!+=7?M%R9G;N+z}v15e0a39jZu2HKKibGbhjcBV4E9V@L)Uom_#diM&R5B)9 z^Mp)yEleBSnrG3uRMeP(q-?8kTeWJ61is@ccieFPp*UlP1~G}HC>HTxx;wh? z?N3IJ0{;Ehuo%pCtmFedL_j;;iTq7o9HiY8 z3X;QE*5wE|=jhK{lWv&qafmN^V({eoTnK%oxP%WPWy9`>AwGk>g?$W@{_J+%pMGv780zJPc`Z-;=!jX! zz<5GE@fKyP4OR!fMOW5NHE6xy*178GigMl9>=z1gc4zMCvI4nzRZ1&N%3F7@H7RX` zLA8Krf@w<5BZJ*b&f8{MEE2p+iE{OGuU!O>3R#cP;@Q+&JdmMmk8dRQ>nn@M^LQA9HM4wcMOoYQ`U&PYHZZR2{&DTON7?L)`+ z2kG{wkWjvaKZW#t^$W$i`dqn;vcDvM1r8zyfz%YF{*3$j*TJE_Ml)yrAK?TE^-plf z`#*=nf7?4%YF19jf7v^dk`gIwuo_VLIyA9`tBrXAb$JND!OK8GggTwJ^T9M*m&;p) zq3nzDU&uW#f@Tn*(=SVyBRhvLnF$+m5+s49rq7*TPn|dKoiko*AFt0fJs=VX9SF@3 znT?T3Ym%C#jH+xj6O>6VE$2nf8#cSE^j#po*8e?c7?xZ43`gE4x=6Q<($j)!Wu+g74i-Dm&sj(H^;% zNk{3X&&zaJwqi#wLEJ06Ckm|-nyk4+S{hxkdn{C7H9s=!eD_6fShJN)hwfnASdK_0 zba1VA?P{Aq)@ClYQ9}=7_;R#F2J_dCu7nl*9GrsyeX?2&1S#|Yf~KAyG~aHFqHdC! zv$tdE9lDp3Y=LUG8b3KUt<_@V^;ZrI{%u%ACxXz62uVkW5K0cU0l`*gfK5b*gPMv{ zNJW&|k64yEUyDnul)l8U9vf{DYDf}vU|q`hI+ZL1PAyb}brO|)IO7581pEGg<+|U5 zu$>pU-8;QPl_cJ!jN4ZRNLs)euA>fOKDRBaZVlIEzc5!kZg^{n%FCewQ0`--a@@?g+{_*DlXkVMP&mLH~!3; zXmFoprIIO2T%xU}NMGgUa}^u!q9Rnwfu+ZWz_MzO!6P}dq_a}%Gr-QN4|mNLe_IBw zj?^|Feuxy3p`MJ77~lWmD$UQ^Kv2t|U(~~4b|kYgotd;ue}O%lFiQfK)=K# z0R0PZo%Wys`0Xbn->zBR5gqOB=kIIq*GSfHI2WN#z;UW2$H|eT%J*F@F&h?=1lq=H z#budAUfFwlKpn)rR-qt}^^%J#kvm}91&$I9TSOyWTH+a2DpiV{?Th1Ug=*0@zp?{U ztYo6Os|Ol;zSlf-r^su9dIa#rD|6osGhe=Imf;-o=Ic$)n`7B2V%gyglEAV4IinLw zce5))t#y3r7L;ndYP33Hp8)flLovtX#Y1Yv9vCb$DB1&c z##c$U@X9@W%Ds@JY*XkJs+x`XJ-g)S)%hN>xFma@x0+e}2rE&MPw<%2)}HMnfZN4; z@`R^mQ~9)oOJc`Z${)rihiqDOpL?LI;W3AF=ES>n-bTeD$u^H9%|2{gpfjwzbQ~;{ zz17yMYvd?E1j9Z0`!|+d8wlsxNZ~Jat^H4;IvpZ7-_6>51{RG_c1DQ$bJouym2Q7R zEt!v1wq{iuy*oSeX24noh~?&%en2jFsD48oYOP2hV-|u#Px-f1@9vfBA&@8F9 z)&o=GtNV%vL0uQVIN-B~@JY$OMSLGxAYs0_Gd(_d_yya`Do4Bs!7hbjHIS%N*Q79x zVx_kp?m+vaHA$?&i&88*0~0%xgrYcdmf(@ydn9fDElpM(TT!E5GyU+vglX(L-h(ZR z#tz?fPcS!f786rfv-&EaqN9p(DcT;VHqf>g@6F(ZWD>6XUvowJu6rawNz{s)#VWOR-{6vtLX?e06V99>1Mm-C5hFg>CmH(!Qz#*e8AK7bKW7jZtwT~Ui zawf^#wv}$o>^RgYbCTXGa^5SmAnI@5U5=e)|NARUcsDhG4+ovY$3B-+jEl)mYgovr z%Xsm|swkW=Hnk?XNlLLIe|W9fDIaChndh{u1B$c(*6ajY=G*EXA~Mk$z6)3YA@r{ z;C40FGsPp+eRsbQ#aQMNxK&yxz9A-A#qo>iH&Zt=d09JtHC7*F(kj2ebVJ6T1q$X5(ZttMX20!*X+$&ylee90olcPO+T-5!-hSn6e z<6V(ufgT$aSx@98^Vsxli^}ec;eg|$i_!8rgG~Z~WAYK?26vD0#>QHaSd|*Pbw+XZ zz)l$~-H-BjumjC%Qz(iCw7Lm(mJPN`itd8GuVdic+Z$V7|F7k&2*q?|!gel1(a39D zp8C^^xLr!g8My3$`?U*Ri|F}=jK{ZIxUKgy+7N~;AV$`O5dRg7H_`BHpl2@p$GnK3 zog&p9>d zIF}u5IO=ELp)}b{$$&EN;zolQ&ne%P}ll# z;|)XCkLr*yX}5YM_zjkq!TZvf1-pkmG;JiCJ*w7rvnJUOFUMPz&96DME~jRBUXWMLxazx^-Az1rkT)_KC zmz}tlGq-_&T5LWloqk3m5tm&7SUGAMPnaDYB z(poUEWRL8bZti`j@Q`;(KqH1e*C{h@;(~CloK-qT7=yuTd|Dtt#;+IrGn*Gsdk336 zaeSKF|B1FEZiwPf;~P5o^{*pq6R{L|^*_B6>>qol(EkmJ|EJSaq^hfqERNv|prHv8 zTnG*LMXV~2u$m68T_~i8B@;|WrEet7&z=znW9_=I1v=vvxVjeA9XJ;Co#2^XmnwbX1 ztgYT4c;3mWrHF#UdJ3Agwp5;{hlx9l-GG6lxe}N9MC01@TFpgzH81QNz!+WE>W`Rr z0UZ#~Na;K5Fm7_TZ*VF!(`#qa(Qi$^7F8_n*GK70#{eFH2np-sFyxqI3<4FVsRD&d zDWtY-#!}te3G0+d=GkzhN~T}xhQ%6Z1q9>0$Q+L~rS3Q$U<^1QAHa;zv>bcYCqD#i zzI_s)L;;s=9=juxW4Kpfjsqy9M--dGZpIPh2u=1`29g4i_uQe)Fx~=VqcKyLx%wE( zX8W`zR_>vAMjY@gpu%9#a;WvxTSTI+Z7AYsM!-6!^q0rb#b00wihT68LTB4J!t@SD z{mYGJ>unHEg)}c{`-;#jVrgU#c#%^=e?{&W@ZlS~4iKEbrlxaP&fw|FqGU=v; zJH`P&eXCaJWnl+QQghr$-1&sq2D7bSctpe3&Hm!raneLTXa&T`&@g5GlqJIfqfw;) zPV^C@hba#QJxlJy1xO`U@#tnm9LpZJ2 zrwjE_4AD^w*BM7wF7u}xWvm%+&Xa$vL0#bd*rz^!1uSw>S*|I+01h@jhn&YKE`dKo zvxCZg`W)ahUv!FxjDxhcx9PN} zo@gR#yl8jOM9bL9)X{rIP2$q8+O4?t2)3r`AujON_9o~^%XT#c34pQ04#~Sd^}~X& z<_{(DyM#lLxnwFd*QrUeyKX^w-nrp;mznG+WO7P3#N!H4OPYjY^i>YT<3by2Cm5Uy zeZ9hs)^u-mGf`HQ=FTr;_>J^vjpP|n1u=hlgu6Y(#`sMjGCT`g!>bqk`emkJ>W-7O zBg1P=?RCmGpp}F4Qi%cSyVbq1y_KmgH*|)f~lGP@t!XA?gC()G@x5 z>gong{OE;qPH%`qPT@`-SJJQ1Z&7}RqUHb&n>hp`vrC?S8p9C$!$B^DO!^za^G4p@ z3z$p1DantZK{QQwfd=mkHE^7G44`-H3h+HxTw8QJAJ}?u7MIvGI5ytjz<-@^uI#Ke z?fsd7afSFNGA{6c1t|aaN{ZC9l{dstzR<9(alQ>B0NY4O3{34C(!p}*9Her6gCU9K z3f42x?gQ4$PnJpFnO*q`>2~HClfm&!JG0{cRLsiOooJT2ganzC@M`Qh;ofQ6|M~U# zDG$W_vK>MO0Mng1oD8ilBIZl!Nr*+{Wgjqx6JNb zUPfQeru0}hI!oq94Gu}(H!G(dQf{@7LyLwpm!ce5S&dY5O(F@VJRv4SeP7xs?H6yl zYPmPKI58Mf-V*dHz2>6Ys&HA8SJE=M3TsoS(I1}`VNde1ldSI*T692RzJ1(dIlk`V zay}}VbZYhz6>v8P9YURHcso2*xgL4Hv-6E%Gk!MY8z3wK#Kyiby3n+AW5`>JmWNgu zmUJpIza%kWxF<`tCToEPQ1lF5;2=u}zT3x8!r8xz30tBS=Bgn?4XlHeFbi;{la)9X z=zvEAyn=f~m@rY9Xw@yTHW9TsVfK;$IF}=X=$zkgAqSj&&aH;Lzf3++z!|i~(o*bk zdHFUAAawYE0vEoC)Qu9?4%V(yD58g(aC%ZB+2*E5Ka=VN4iY;kl5S$m>FJH7hht)PBw_cBNFwr?hDEydoCzEnV7CZc#cYR)qX zt+;J5P7#JGi3+j$qbbPlmNpA@vD2e`7*$uEI?bqpP>#xvrJm0iLyT_K6iJ1r#K5}j z>394XahETG+#SIQi8+sgZnXfZIg&k4!g?NhZ*zNkhT{G8Vj1?Wif) z`%wjt8f;L+71RkO+Rfter`d%_pePqAd&X_;A@$g2_9|I#sqiM@O2O?b!y;ES>M3pq zIpm0CgdBv%``?H@FMiwj^Xf2q?SiZK8tk^&dB2+!+Gy$SLDB?9ZW$$ck0M$F1w-J- z`$0GTK%UcgI~#4s%`oD5Nh8Nsq+(yKbiP0m-px{}4AKWRk#3S1#0{NuZ0QqgX=0LU zso)b43br_OUmAl%qGm}jLCHo1urW{cobWql<$VET6CKV*-w-Pep|DfY3cpiCia9^#V~;B@O3<80#!l96>Yjzxt4+&}{t=56V^8n8 zH3-><>`22mVlrnQ{ZZ+HzjK8lBqOz?iyZV0*Fme75mg6TtsGiSST`-UH70XA1>FIi zGN1NmoTGh(YEQmNQuZ|-w_RT1G7jTh>D|vyN%f*fA4hIL%oWf8^D}#}Bfls%WMqKX zUTQ?>8}N7#`->AwrHD1JGX#P5s zHa?w*T(^{7 zbL^g0L`U3$%oWOHFBu-BL0}u;#3Z2<%N*MqrDQn(0ZM^{R2M^Yfz)qf!=mKhhg5{DU}s3ZR*u5l!_;UDNun{A0We z2Kat%(_Q6BZ?$#AQ@1eeE*PC>dtJ00X5VHWW_S2?z4qmN^G4`_?I)sFoN)wYQkiKe z3s9v@YYVVko}UX>ZL&&EPLCf5&NNAuOh*Zl%PlCaE-#C>tSp=`j?kPy4OKh+0mWK{ z=5nq$)L6>L?PPao;-o=Ugy}j0!dbyWRddh?`p#ifpFC-m%)c3FNv&1fovB$jCn+$g zqU2O;D}LKN>8p)SH2=37s#cuTKXNJRPPEJ}Bak=a26R`moNGM*q-O z{E7lHjXM0zn>Tb4g7`5#IpEcvPiage-O>uUjX1}%iZW*+TlD=7L{8EB^fjHHv07?7|vz6a#-j>#AI-$dQhdqU2 z&U&7;%1G#tIKKdL*che2GFgJp^vGm>L53(2xf_0P065U=ruga)cmE#5qVjk>`WEYK z!tcB;2OY;<1<>6mL=BbsR%i1TW8P*(M5atDQKG9YTmgKJa+j?eFHqX74`vf=`(TeM zO{!(sBMNVkzOWzK4JYZk)k!UrVvuAg+zY9?a}}HvbDTUyTUP8t@e;Kl{f4;54V)<)X4$mT_fj$|vdkC7W;Y%SCdWva zh6vj%X&vkpswY_uUSK2IOv^34gd$oPXMtrJQNWY_-J;5{~uOHks`cSk@WEP$> zl1*zUTNf;o<4kL)p3;n5HBhB#vkzga=fTomdUNQGhr@f#9X(%^nwHqUOjJMo4+J0O znk%Nthh5rzJjz5Se)$r2JSz(2l6LAZRAweGWSyFb-Q&e?VhQ`M(7W>_%~`7KvJ^Br z0)u(zcswiY28(U9CUW0!x@>d~JUz_j<3Q#hM5|&;ZTW9MBH(-waWY*Ncp>p1KPr3~ zmkiza;Epy2`!=~`akrfCvVeH5^1d_RPP~Wi!Z&@N$lQeuWQS&-2^4o^YIcKOWXmdu zYCOT{4h+;n->xt-hJv%%4!v}BN-0ec57@pGLwnKcd}Qu=+#>HjbI<8zSnN22+&uvi zX4ApVxw?Ix5BurNhp^}5m`{Vy8R*wOA>zdNt z(NSw&FSilifW)pSafePp-f8+jXazoL3_fu#Tj1;w{kBKp7=rz_kUzqhKcXzwhAg%Z ztB4}pR%xUP+!NP!B!1^tjl`8Fc19Z)3@iQ+2C0agg%bgB2vhvInFDO)4Tfx$tGYSTcMK=hi;J4G>7<1H)>YtIX!<;q7AlIbPNdap1%_|bTibeh*#deUhV-RROF zdzSbC3i_JZ@RNi*55LuAbQdBYUD#~*lL9mJGgs@(dqX4#o^S>M0!NO%11+QRlj}Af z?66bn70*^*SJAmy;anlvG4bBDWN|S<(GQGIhppaXV%+f}fa_7x=%UGm$Zw8~ap}}( z+oz>#6_j@m`-LOGKG}jMA5Dtd0FZtgv~MAamYI+3AY_?cdV8NgXusmWKA;kE?NmbU z1oDWM=nczmO^i1krQg%BZA$*qmUYIlIDA6!JAvmQ`%IKkaY(p~XF{!;9F){X8{?71 z(ecn!XKWep8#Mi?g=@I4mG0t_Z>#FHXq;H?x1-NnI@bh^-F6BMkI5QEkf`;|k*L4$ zqQnL8y@)Tk&R&Xa90kT;v7je+M9Q;oaJ=wIP=+Q_nN@38MSOSSM&X_VaaeZB2O~G3 z+LxX0W;O9G({ChfSLZGKl3oq<*$Xc3^PemG!=y`LSuh}=P}sjiOp^b-VXbWEVq`9E zU~Bvj)b!6Ck=S2=>i?U6QKWjR`j1V8EG-~Nf!48%5Y;^Pk1&h^vLSWzkNidfEg_1+ zMFU6tSy-mZKg89%ffaCDTu&ud6f3S(y!?3O6|b2P7QjKI=Q$j&XAO@Z59eo0ejoR% zctEy&k@&r}h7JWgh15=DD%;8X=qOz$ZDl+co=uc;`-83nWf(~#?K;iwEVLXkZ@U4< zo@)p5;DXRl#PTkG9LsHQ4$A<8kdLj~9P{qeYkaj&O0TJ;fjgKgBlX!1Ev6pOkB~a- z%88VF(sd$iWA+mjskYwP1nW^r3$;NvKC`S{CXmF_4bAPp;YT@4a6tz=KoRbS;0J#O zkpI94fN)_7FaQ*NVroMRp~DZ0p#(WZ8|3P*yh+&jg{ZOJ;Y2V&qhSlRu-=zbJiwTW z8wU|=S_zjVYY_jgQ_DPL9Wc(HQoVE;VZ!lhny{g(NX}0kd_~YU5x)no)Q6l!&OUzG zu2~_BW&BPx^y>%=awnAG?ikRgQ{KeiUaSubA=x>d&IiEix>HnDpFt*e$ReO7!7$}i zk0p@0x8}1ozx3Q= zmWE@(x1fG!&j=JQjtB;V4p!tjem!v#t+=pqM*+k`(s)tw%cUAcK&eEi&I~hobb_lm zf4C$@F_CFfw=2P0lPsLIh{D~c)b46Kux8tWGUn#8FNarH-f5Xbuiy4f+^T;b47D9=so6}VJ>8Mz_qjFG1mAf{Lrm>1=C%$+DXL@y@+IG z#iPuidFX8G$!F6v1%gJ!*;L+lTWo$)heWXXCQx&FS6#Kt%;=PS(Y_Y-Q@AGco}V$& z&6hC3MsDwyMFYm{9XrUe0USQDF1WtEJh#vw1QJ;|de-ACt(f9BO|hmuEb@4z^{LVt#r;UM^qP;#sx_Hz_PGLp^^sm2-NUg3dUsrdff;x51qrkbvyru-%S zE|clI$U6!fI;_L1$`y(P7|AGo+Yi?;(iafG5;4p*MHuUWmUS)!WuRA3N>Vztz}|cD zcT=MLR=B%uDe0#I<+!IeTo~C?3vhM>?+ERC{S0h2y2O#=CeQ+pD}%* z7t&I?P)Ko0B)w7EU-}WH@XFy%8Jn+g``U4dvgC>c6?^PkE-L3MAG^t#b(%KjQoT zBvlYN`sd@KLq`>g{p*D{^tTctx&LXuQZh2IHu+DRR+93n>a0Bc`YfuTP;5l_&r)s5 zW@T`;8j&wE>U=qzNnK*g6s|claV7DP-F6?})=(2X9h~paoIS_3%!E6EX-FUQi9gO0 znO%=*9Gkwr&yf1Ca>#?=B3jCp)wWt%o-#|#T4iavTc=$8a3|SQw=+6!r%5a6$I3R_ zMg8J!hAW0FqZAsx_}JSN;_%7rV@_4&-F9IuFP9cngz!nd_lhP~Zj-2VnSS&5jbJQe za^vu(QZ$5P*9RhFbpa&(g6;e3X)uC>m#QL&L9#G5=4uFHDL+6D!LJ*ok7zZb-E}wD z5jWb~OrQkyew*N86`M))AV`ZN29;C=nA6fGD6NSz_6xT=m;Y(|V~Y5WE^i-}+Y%}? zfDZuIN$xpr?*J96FGn<28ltbJY!yW3LGcGzp%Y}TA|MbABu>jq2o0etLJn(8FCKK4 ztrj;FU^QF)z^pb3$kp_nUQTYI*q6pa$Y=yWlRkS20wZQvr=4jSN5?zWkIKL(rII!V zdj!>yz6zOcA83=A(wFEb(>rQb13akh_2|#1CObO3?t7uj%x2O^&9cPDCGza7T8U7k z9VrH?=H62nJ>>@8`SNR&zc!wI->dyh37DyO38c2fa9HN8b!B%Lp}Qdk#hM&`2VFDW z5w=A4oh!rs8O<;|&^3~rtJiv@?5{1H{ZvDe9h<;67YTXgv&-nFb1w#betJW*X5mNP zXpcPa7i8mdtXU7mZf##|xyN^bJ{WbDCoIFgJ%gY7q|T0Sx=wr>njUB-wJALk$*Ba~ zwoa8^MW2o$p_0Yq;%@JJJLsq%Y3veZKO$d>QLcZ*KSK=U08F!-h>m1Gwdf0^JR_p>1w<&QKH__NHrW=%KQiNCkyd^i> zVRT3Wg6|cb4|OPqzM6sFS1$^}JO4D<*mY~}|M|*P!uneqCd>c%AL(Dbv$}_VrU=UC zIPS7BlZ6vA%^e|)#j^E^?d*)ACU}&E60ikQ0=#&vQOENNwYA&WMKMjvXq37@>;MQd zXd$+UISE7_u%kLMyfQ7Qg0ix_FtRcw^82{=Chqb@v&1_Q7t>|N;X4FA?%_Xwk4ghNh5l++F3XmjGF^HpSK)>qZ2w{B^DLFz3yj0(nQ zSiIkh$tFl?5zJG~{LF}il>Tip1@y#qS#QBFUTVbk0uE|1fYmi=-I5PVdM2=x;VKQ} zDSc^%YUtNRK&0)rX%RC}Bhp0TCTjH4s}N6^^Alp1co7?>QgYnLpai{9BZ!$3@s?@q zlZ97Dta|?rL0+Y316$Q4!()(P7Q_=BJ;AX?pC)MaVhNc+4bs%Ngw9$L@fhLon@ zOFSw#p!&%Ykz#e}~V+vW+0~6wKqEI1XJ$vvJz-1H_|-G?Fu0(qwTw( zoT64btoF!B)>mtPMRR#k!}GXrE@OLjA~usYHg8y8u!6k1G&FmR}}R<(UrJ z;q5`Ce;#KsAa!t-6JoJG48t(xw}ZN%D!6TQl%i|@mW9?Du*bUyd>q_08Hq?(Q zC4F}tUNE7I>PJMdo~z=7k-u$sVF)C3cM_pdQdUWU)KVra4nooFSB7`j2AP?{VUY9( z-t7lWucL45!GU(XJNzgrrMZC1>{{tj0Q(*6v|J)a5*eZ%6CL9bZ##3iz&!bDM+av* zr0k`%N+Sr0gg53E)R;KaP&sN_@ZKqIa7cZmrcd3dl>}1*kHwIIP3c@QY;3NKv49Kx z7Ae66o0aiy`ez+OHm%eaWEfQw;+V+`RSgm#%+b*{7P#*{HTG7SH*}z-Tq^YBh_8gh(D!@Gaw*11f{^X0>b z%>JxYwn})cl9{YZw35x(bvWZ12F=zWE@qhkadQy)z@>Z+YYTvk=BNh*Y{ZoA_L< zX&U~KHaK}r2s0h!sZ0BFnf6%)XS9w^sxv>fm4$U|>dl;S;&#}S5!B{^47+--ryBd2 zYUM&g|VJx51%rj>h?!Ab}y1&+S^&r<16OWs&qVV>Mv;RhBu}Rm;A{*aYcC$Z~PPIODeogoNn_uAh%snW=(98J89Wk zJIcV+&*v9j1O@}z1LN)RgQ-5lxsVeBT3_L7p3x@)1NU>ZV~vtGzMB7^EtPc$S;a1tK}CXrxjP z%HnG`PBlEmihhSWH}DV-obRb+zLfKm)-^srxRX8vosXPgpD8(XIMl`u* z-<)T4S(LgP9c*LA?s{poE8Ziz;0(9v7jAK^_>yl&d6AvW%Www)yzDsPth0q#qAMKf ztS(#}=a~1-o`~Me?RD`ER$HDZamYGP4u!%WBVXBE24XYLN}FxaJ08@vP>sA6jv6nl zr(O9${Y#6~(~nL?bJ@n>w##9@6V=^FOyzikRqv_Rpm};^6RI5x?J(I{tpjUpS+C9a zMv9Jl3YL11Ss1BOp%;ppo*0WMOdi#}j=Wg1xo9hODn!}l0TP}^#A|_G5H1b2K&*Ns zJ$h;4bv#W{i3!OJF zYj8Pg*JQ5Itd<=LF`9jkm)eMdHGwl)x4UiMgd#k*^mbqBqhQ~Jr4TDI@DrgdirxZ{ zt4X%d! zL2FDnwL_j;ai#3PTfK@NyvY1{<6V&Cv)VHaT9WegVAu>;U5co4DIZ)e{Mua; ztaSleov=4Ejb!U!LhTv~paxk|Ex_eKJ3`0d1aAYgkJ^x`Oeifht^3E#K>Tb7lHj5D zf#Jk@*IL$~qPA>je|%B$a)f-?pvX;T^by-tO>F{m*vd7PW?GFWk`3g~Bun6v4PJ2? z76+A-15>o@>%&*~{j>2*?KR;<-EtUq1&aC_ah6UuJyuhQ;^%2e#dGE621lcW1xcHT-! zhe{4oC?27DPosr9a+pYh|^ znY0iu;bb z?-bw#oBTbaVcGu@ojv*-(C~hR9g$)G9WzJw-vj8Hc6K)ZI{-KZ$_Z%^W#rRJib_fs z*P$;$1{$JC04`8+otP3H(TMtN5Y7T2hcum1@(-O2gyYZEKIyMc2*d$NOOq@Dn%hU7m~(xm^*X zD|3!cm}#Z=hO9|ENeQ-2!>DYLv5457%kSpJs(3hD7%!*aQO3+U)RiJ7YL2R-(^GBC zJUngO+#Eg@ma>7Ui?vpRw24{9eG3dC@0c<%tC@8>@W7=5NVa!egn0>JZ^H)`xR_y-Edq zs4gJ%8Y~W(!JG{d@j{z}x9GM5eUWD~FpOab=zeF+z6wN6wxRZ3A z`EvUhI0vGRLzW3bhKDCOpUoUk#lw5d^eTnc?a#PUm<%nG?ngF_x`3nzh5^ZLN5Vz& zOvTH6mkX3xXfov>N>U8_&3!blPd}&GBAJ%MLLcd5T~RMGE8pPr5L-m-jq89X%7SeU z80iI#bnyA(AaHM^9huE^JmdLf3X{MG8l)Nx{LY&`#ygvfJvwAuulujMt}AKJP4Ej$Ow z@rQ04o7{#Z)qT5vfTA9X%XDwWO>xaqG?4&vA`E+JZPqAP<7}8J8tP%p)g`%l#%(+e z8{!Z{66vW{V*0pQn+=r9B@`DNU3`QQTH8sy)hUhBC(`rvClT7VCu9wl`**$lDtztr zDBgmLYTS$XPjf1TtcP8zr*=3tcdRpZfvXMT@oOM5U!{{<8kG?ThPP;ct5%BimO|ON zBa1do)RX>vyv-3fpQmqhNedU>zVpQ!O=D+dW9X%4r(FHuOV85zu6In1aZ3w}^J&CO z^c$jQm`%nou5s%e=uP!k*w6`4@@vQFBthT zaZi?oWPIT&Iovi>)12+RA{L|_!Cu)81aAzq>h%z1Hb$f}Lw}D$G)|@Aj*k24<*&}_ zXi8eoi>XSTqIoINUV$5rM2P!saw}Zop#=7NnxZ^WNukuCOi2sylvsVq+tC!%y)9tW z^|eMSXR2Dh_*50@uE0lVHE#+U3snaWwwEb!O0*Q~mfVe&*s4kDLGEh8OUko$0fK`n zjk}C&ZO-DwVi@#dwk)l%=M&9=yI)>nI(D8Mt9a3=?Z-@9(w{zw+-@s)@*E?&KpG(M zgemkA!tQ;rH|^n9h+GpcIlWTex}-_K8aifawsF5~P!EN;{rT$k1?kQO&8J?)8FpLn zJELF-Eq5zx^b-`h-m3*`J&x`@w2StNE=%^$4lZ3pcX>^a)(w+dNi^zKt%-5h&#cP) z(N_4-)d#Gck5vtlM`g=xQ?o-)BF5TMTWCuh8F*&+_=$a1F$?AF9s2KSIz5YRk7(05TW@P(ZmtN(OI(PqlMV%^GCTs^0Lea3irZ&(98 zw1+MTC6N6BG!Fh*%%a$6wEzb}cUTlc4_FV~Tg$ zZZYAw$GQ}KnV93Moe{jPKRR!Ja9D}nd0tR`Z9Vr4sLt~`o`NgZ(c-4hetLgsF8i+O zy9T9wLrWWnvL4559=N>r9e<); zQO5LSzbX69m@ArM;iTblREZ?|XvJ}LKq zOI_@2oeeC$BKrT58Yz3&oBT`gqNHPo_>~eg3yRuo6=7~6b?T;)ixPn6Ho+S8Jl1|bu{yO%3~Wm}SW-cJ-_^~4w>Ri)Gxpe~ zk$ij^sZj2bFR}p$3qAE|=nkn+DZNA(8I>9jMzyMB~AUsU3pf&K?OV_F^;^mupeA!h@QfOfd@@y@{QxYg{1%urbLJv!tkl zO5nuA8M?EKYczWFpU#N9aGoa~K}-NIC&bmV0k9YfdEIdRduss?QS zRuT=xsOkl$8pcrVfj9hidN=JrAP*N*26YrDN8yvb> zW?%o)Rsr0H)I{j!y7giJ&3Bwz`^UA8NAE|jO^!p`uLQo9&2QMlI-m^x4as?nnE@sf zsFr{)DXff>PYu1DyYDOuWQw$raCKr{N7!C-8jYZ?`@=a?ZvEFXBfPVW)_(4}@d9j~$i|?sJx|M&%>`OW|6jT;7OJ#;=x+Iw;9nmJgk>Nz=x=ahUTYd9bl+~FlZUK6!kZw`zP%z_o6I(8w zdHOB<7al&!cfX}=rcK*U6K!bC6*0c`Mc!4@rS~3C=*`+mn@7?6WE3up<7dI#xSc(4 z0FPwny}#H=7B%C)s$lmD0J92CgZx;CW9wC)c1=e*QRpQA{qwu~&{<)5-Hw4BlEtu{ z)2q6O0kE;gFYK~0kIAC+2$^s;jyUO#C5D2HaHQ)M5>6NmLC!hAxR#bnB{^fIJ`|>6 zS8ZyKcuC=|mTShNp`00y3o(-sw<@L_Sxr5q_p>Bxh{NBeYHNp_OUasfT<3RiJk>Q> z4BeIw${_>o6opaJwH&8!sy8Ecf);IQYpB%P&byfuBb#d6I1Ur+@9kRt_R-;4>vjFm z{6C>(e`>`Qqr#|*vQeY;&4ve zE8y!t9vyA?oAN9_G`mPbNJPbjevy5bjB7j`uSAbz({&-vyhCkm$$Q=M>-YgyY+^t? zO4Syamg<;ZZJQ{)+_1VR_**I%WR4+YgDCmH15mOR-8*6ClMhmV>RZ@cH58FnC@Wog zbe6aYqxn`Y8Lutp#5$-EIr(SnLyv)i-z^PFKuA7JXv4jSX3F;^j_Qz~S1IK>h$=S-$8kMHT z$Lxxj*vqjx=wn->*PEb0*ITSA;a0>exEl1O#RAA~243d2vCG-A__|9o zmK&k7kyiy%@Rrp5#9#*gSX}u-_<^Dg`y^!*uS#88EDt-QnU`rYx)L=j+}4kLN$417 zMUl-oSW)xG7|zKBpelxMfw)5_3tBB2V9YUUbQ*`h@&hzZ0q8K~hxN`$^Rp*nVd}br}y}J+9d+gyk+S#|)_U%{u8wI#!brddWl9@|l zVD3$2j3c}et4ZtQ$yk0K+*+ zxv&(>g0N_f4d}^jtQWK(}JU~c+PJo|;3cqO7KVvuYif}PvLG~H+ z4T~0Ao&@#{$QRjg;rd%1Kf#Gfx9i4i=kod`U$^h~+6WmqSb|Y@376C|hg8SpW8x?o zjUc-=@)E$nV)$#bV_}KJ3*!VCMuw~k2C2g^ovBS6rR2o2yE!~;;g~rKgdDOTxSx&J zFbP=^YgQhoZ_agvH!fJ7MsfKOH{lr#{aW`{PPujxSPf5@U!nJP6QtQ^L&u}Wk?9@s-TH#(}7OsINK#JzWlyQlu6lf)VZ<9Td{$zrk?FRAMIYnVt((pBRN2%b!b5$ z2KBx7okggTG%S-)pi+}o&8MYYYYq{tYB`wP1jJUV3X^merq#XY_}xnx|uP&S~aoo$L=fB5OZ&`CitcG$8{QmZ+^ zjA_$1RRK>Tw7>v*BMmSwum=PSM+IA?Q!=X4;dkLK?t<5a8=$*`l6DE)r^|9-bfBHo zz9*LkEkOfpL21lU8gM}ubA#-Wd<51EL$#TmAZ-hB`sZz`+d99(vm;W3G*oRWJ2%!(_#BC`6atK{+mcW~IFX+aD zB$4~^^8=(K3D$F0qUw=!Sth?n+(lD7!S6!baGAlNzhD8&f;q$(Tt!NXE<(O(YmkQB zt0XvJUKg?=r6L|brEVX7wy-uG{Q@p)r94YLI-=;=tRvBE65NVJJFb&nL4Qllio|k1`bmkL779KYTI2xhBP@C1GvGPi~Ydkcm zWIPM@fsEL8-Lp1Hrg@eQ9k)P;LBoQ~-VJU&+$4WOr9(#^+-i@m zEkcUQvTnoX`&_8ph!9_r$}G0+1|1`A_RNrk&zz!;s*7kHMgT%PTas6vq-^vG>=j9~ zc7+9;urELi=p*&2wWguGWKltI!obwJl<&^IPLh?+hf?&m^ZbMqBa?o+=BIlDpQ03} zf=d?{tVvnR`&x(}l@%!*HRfe?FIwC~SwOxPse7NH<1pw!uo)VWc*940MsFZq3~m_M z^L)S#oHDpZ#u*7qh9=0P^g~d*9iitWUeO=W7(B2YA0zmLfMeXHgVOVV9WQYJ;c1nU z@k5q_7eG|tCXMp1_lqY1;>Z{Qu0v`NF}%q0h(9pt_LxES+FsIHWB52n_-Kvg21?nKZ+?Hnf4qmln1vh2MxSK zWNwi8`MOImJ%}Sr-9LwcyoAq=>eY~PXUM@{LBj?to4+eQ?I{a?K=K9xs=}|aExdwU z&rs)|3sngybcizwg^y^hR4{(*EgPK6OvP2`M==vJ;u~<^jO@E%aoxy2l?Da6W0((9 zg`1=d8`RTF7zKzzW&d@H&omtHr}?Wdp8xG&RsFAf zlz)&dz+Mr^^QL$_M|BKrZG9e&dSWWYjl7&^oh4XXO;lJMdQ$7I$YGd5`FGiVoB?N= zUHYrEC13bA?F9QIgEAI3WN5?Cys^6noRZ82kw}pr&2&Z}1&D^wyD~Tm^Z<6DM}o%& zmBsyLz0xDsST&g|Y4TL$pSZvv(d;U6_{P%P?LihVx0-x2DpD_ux!ArBl9@@RS)q?udsgmJVdoOe)d zrPPf>*#;=p`*F(g;}8kVvK)&}P7|pC%8c{93moR6#Fy0pUW6VB`7_uBCtdI>D4>s@ zGu?@GfDlAn_|IUZye)+KMBo}#=Y}ZEvrfHqQMtY;g-SG_fj!XCq*2KNMXIOvYg4V7 zxmO8Vc9q4gbc!JL0?sTX(EeQO6h;`czK<0^gNBtNI&M-x*93_G=@p;AXv3U{j#=kt|6hUm`Y;h z9QM(rj+vlm*=!FHb7I*=GvX`WGs|q8a_ably#XdKjA2Zb*+FulgxIM#kZX}~bqb7( z0E0n^^jywVNbRu2Kl3^WB`$lv(tHb#(pVgQ0~-~BeDP6VWI+h5e=yi=Go1T4Ln@i@ z_@l>v|3!53&(mXVHkA%XUv!1>-|ErS|L6a;|9A-SKUH{UB~03WLD}IRhqYn}XqY^C za|n5H0zV)jWq9&XDg2+v@c9ZV?D!lLON?tiWS2THH z^K9b7l$+_}{&hqSNQSw-7ThlBDr7~a{t`A=aRtxQ0J{y0FkCFpelv(LZpUf$?BVVg zUiVdiKca!j&DL|AlbUE9xNvH)j5}w}E1f-NSS>c3iE^8i`;rdzG%6GB82_*wc-2XM z><_*`TaX{}Lp%4o3JIv78seGY=mU@S^Gmo~Fa#nWbHs z)w!QjTJ+BzRXZn@NBWC!O^QKc^R#*pP1vmm0k4uHieQt72!mD2WLdK3T@=F}U}klq zwSzqU!`6Pg)5Lo}G6T_`40HIiAYO3@DgvY9`~3TK9pqV;vRb)hh*p#yM#EQDd|LpX!vT z<7;)Jy$5Yt+wa&~j|SJ@kx!y7e=TB#*mu`i7$hy4xB^>}-<%Y-|70S^$UI&^zxMBw z8ZOvqZOW=#{Y^08!!z8P#poLSHVj>`;6T9RW*?W7R1RZZOu^MUIC^k<)2W^kGh&&I zzcAlZ*F2++T3yt5T6)znNEv9eCf!h)5Brya)W77hALy$JzkNNY{yk~-@9)6htSM5GACM$lGb#2-gr(vrWu0wbWoB&s+ZFP& zckxPIBp(s4SB$_k3y7vIaX8s@(adb(4{ppNpReyL>=v&p3p7Hr&i0(oY*L7+PHXk$ z+?SYToCrZQia*uMpFMd;Nh0sncc84NzAK#y7)BysnXj2Bl)j#b2jd*kb#W{bw7W7b z`ckAn;!iv#pO|VJR|RE(h=q+Z#P4`LBu+&1uN5Eyj2gsk4~5ZYN)=;vm^gdfB#ItU zCzf@Kl^NPfrwNARGU1c~evu_Qk@_i5cn|qEJBg5Jh#@8k@<)Y|P29x|&rju%!2*0~ ztW<&YSWZqne)TgcbBk0G>Kvys_GT*1!7QRP7;@XlOp|vi8&nD$3~EXpTln(N3aJ)M zjZ9mK6-XMaFOX+Id4?#d-j%wk$jk<_)^F2a2wl;<3V$t{hpzlrZDL}`QUNCN^Eheso@^f8o}2;pUV7`s;1fhK z`WQKNMeQ>ws%&kdRHnX6+IwqzU)ZGz*hxnJtCA)E zwx3e}m;Lk~%7OoPACaV_BZv95j~D=kIxR=mqPFa*0@iFvZ-fg*hbW?;5Zobzc<7^E zrKr?UZ=fc9t3btLwy}I!!<)aG0H9i#3$iV@IbE!I9jvu6eU)w-aBUzC#y0>_gE9r$no5d5^d2~gNs3SCg#B1{lc7M(GW>ef5#*8Q(bL`QQRzCz)*j8t6u1aZp_g~RsYB`26U`0Uz(mPK zi~!KX?=kp=KM9I=Px-OuBPmydFYa^_dg=xRCO(Qc5FM0rZJXKwONra_QEO|B zlx_`Pt8=_z8-n(96fe-RNn)&o*47ets>1Nu{*u=XLF@+C`#k|HJ5Dp82a|PMfm{N3 z#NPI7dx6GJSOgZKpj`;qgn4X&Ld5q@)PAJ#Ko`@cv7lkr434dRjKRWvJdqCttvHf6tc6i zH~5!DKT2804od`?$EfCfaJeu{Yo`z*$^wF2DuV`ZzktFb5(f#3457{{3^}g)+@kZ? zSG{8wn6C3N3vEy@G&Z(&C1B8L$WAbnt08)qSGm0Ce!b1g7BA1C9r3TXos zx^2d_&Aw)Vz5MbFk2xCBD`{P@puWdVx!o;S7hOHrp#8`zuakRDMV^C#?wh4wJn(~Q2!7uu4Tdyp0DvuD@a2den#LNdi z>q0uT=Je$i^Ukl6)=*G@yKfZ-1YnHw>r6#I<3Nc!?y-vKl1q)=Ea-+CR5Co zD+x$Eraw6(k3tO}M&zwp#3wP%-rE|nH`GxBvg#lt&UBVp_FSw()ov+}f|EGJ zHZh}r)}^OrFyWii?oG{@Rd7owqz8jyYa~c~qvSLt0K(Ipc#dn_znX*d#E!Hrq=u|xX3PhXZ%|=dP*$T*2(3`-Rd159ETUyl)n4| zS5Un~fd^WJrQG%wPG?226NX2n0_scbR+mAuOn97vgi#n{)^2fUdiR90!pzr&j&k_#!8eYB93V4j4Wsyx95ccqg$e+1mx* zY_S%9sI%=LYWP90#&7Zd{-o*i5!=CyyX-?hKMQqDCQesr><2W6uF*FB6|s2^V~^FO30?Fm~>zRAgwIQLeNyVVpzhr4~`c< zu+Q12tn3ni<)lv+yvJ6@kUkp}KPwM^Iq~}kF?p24sMz(Dk!1R}1B~h4wgwwJV-ssS z0YfKeM+2jO++lZg{>Nq1zYtiG%KF!ZFyv2~AdvnW4a7okiEmf|CQXuj)|j^frH$V- z5fyVO*NLU-oqsd_23VX%(%tuAh~dp)_*{wP_{fh)<78b=gME_UuZ_o(j_H&R)P6OG z%gfA7j>pW5p3mp6fTWZ>_bJk?_~O0r_QEoavQqQ(Y^qU{0z#Z450QlY<#2^$C(%rd z6l0->UXoltJ>GZ{8CsOW`?KzNCT@GERGx8#0so(QMT3scOlcc3WX&@jWl33swkOp< z1|s}&+H@+=ZC~oAs`5r8DFyzPH}xv(A?JZ9I1p{|?9r6y4fv@c{8b5)N%$#?{@Is2 zpc;z}`TvKpcMQ&~QP+e!wv&$0v27bqY}>Zg>Daby+qP}nHhQwpJ5}HLrsnKDRqOZq zv8vXM>%IUZQkTtTz!2x4GCMbBNK|F%q28lc&Qi#$tPv>-pUA@@HZ)tHHJ0qmLWeeX zr!POLT(B=~KwqW82qz~s#Y36!XhD%pKB_J~s@TK@JmolzFp!CO%B#zeRqZt_Xlox^LaLY-L~FqI<}br!Kf%I8Jh+M*w2`hsI!QtUXTrlx4Jyb@Ia=V#Gnri4g0&P#SoD{Q{2$TwVwP{pCL zC*tUCk9J+dsMxZ~)K{xhA=W~XhfX-Zg*L0WoJaU}rlB=JFeSg`?#Sz*0IvN~=4FZL`y+LF+0YSQo@|?C zSX*u87nd1<=#Bu{srCbOb1w`!Hu9Wyg`f1Qbn$#Z|{XI z$nD$6IpWaBIrFFXK>7uG!Bw))^%mi%L6>$k#ROtiq?K;B@WiWb?F%}%zwgc&>wNaU z2V8hTU|Pkmc`QPj4I{YpC3^E%QpQ-^JSO(O?E=U@20+(MAqyQE!$D;2@rS@p^YMKrOb1OjgaT7Qu%CP8}p zzc;&Aaq9TwH=01G@tLa~ZsWgucpXJ7qTVRBVY@a1cKb>02*6wYVTY28%lu+7W3P(+ ziR;W;7Hw@&LyMb7C{XL6#8CBT{0C7Y#G@q0O(?CyBz0qC$aN^Ah(}+TXzKgOP^+Qb zJILzCD4{E%+{6)Hq9Rugp~4r!sI;-3D?7i3eH;9qTX#_B$m%c(b8Adr`Sl0>9VMeN*&T;|mmNXhmhVruWJ#knnFC4M*kCWhc^ATM#3M}z zLZ9%EiOX0puGs4q;kpkz^%|7dEP6h6M9d}+VpD^=e{}vw6S}&GWA%Kql~;1p?Sc!GAVG z#aor_M?~ky?y)bLm*g|?{zf=_$*vDJhRW@y&p7|kXm@C+fp2mfrmA zb>Crv*`d~OlX?8ru+l);&~^-LGh&eHwZde{iH{pukZetp#>Ap9f5qfVcv=(rO=UUm zcJpCM-;2vWWi^aU0b3ScwV7C)0xC1qq13{hBwVNgnQYd5yABSMm;`hzktjc*5rG>l zU#;NXYn57+*a@{^%+-TJ{~B0>B%5RLPV_WHN{Xg99a-ZE1=$NBGEToz+$@q(T~H$C z>W9WG8Bv7n+ARh6Cq@kY68A)!aZ0T=RvBZ^4$k`ub%IJz+iyZ_q<(1cS-E zqfI^5wvO(43w>tH?4T4yIpd!jFf$gC{hxWrYh`UDg35UkB;N52bP|w7k#Sw}p7HZk zTpClv*LH0g%M%qU3@bV~9uVCp)$Br~@f#%h zAY$Ulq*em8Gcm3fHMz`LqK1ry~+47i*7tD)s_8uxgyo*O!GBk3Kda#aA!$OddM|X8f{t%8M zvPrstE=&(M3}cpIx{gbcR{6nWL2uZqJMCXq$3gbR^iQh>eMFrXvtv^}!UkJ?>;7e2 zgQP(z*~DpW1NgAiwD2Q({h4XtNS+3+9LLZj`9~0sMZOu`VS4F&=ZNwxPC|=eOy2GH z%y%kgc!vrow;9&Sdxl_@mS^7xKG|c%5JxXN3@!=H0$&@0j6q{L$Ln&|8 zG(7{VB!p1Mt)Cfuad6{X2VxwHyG#RG6Zzc379jV`kxZzk)Ta3L_P9?Hy;CaGe`&Oa zd2;tn*F4QsY;uHfbNyi$P?RhPmI#jEBV8pXa7gy?&a5Ksz@H zOShdj&nOEOsvfBH$dh#9%i$1LZus?wq31f8q6!V&VnhILH`XkyIwMK<2=m7uc#A8C zUtTfG zGuqYmkF!uDNndHpGfLArMkCpdpGR0G*Vly{lFB9lNXOrWQ-N$jI8Lz~PCBC2UJjSbzCOwSkUdnQyy`HrGnBe@j?;OJhz9ip1S4e^ zLT_yPc7F>sR<|OtB@eMIrS-xE03)udMy?n zi>+xG5k^K)uHK4901EC=lB5LNwNWxh^D@Q2^5%vFm*p|dvQ8cs43>sU#h+87!16%~ zDPx!^WViq=&wku#V+Z#pri`aG8pbRqojs~{)k?T|jRvOu0VM0^wKVThfMeNmL!IPn zMm?(Ll%^$>OdDeQJ?Y@GWa~%SVH@iu?$#{Z;qt-Jx{@`Xb6pfy(J#cPiTQQ=uBEUa z@EC5O*)z8iaG9FD;m7w&ETMW-@O%7_SiHtLa6t`y;7_?i8uB2Sg-iM%+9!}3?Vit7 zPKMxk{Em>ad-I%83(};G3+lYk;8}u>B3Bt9(^*;K1w*D2sp<@F6a38>3pbb`?~;|% zSZ;`uoT4n;wTk3%Q)e1OTX-=l5eXZdHaX}Bj={!6DCgzjEiLM3L zaNwJ0!PqW0UG9S+u0iGT%D{XYJZo-IqDPt%UUNMZH}rwfE~hxL$E9n9Sidf|t_bfZ z9P9bKd>=DdFn<%+m<4tGDt*|c;WLb>dRoB`{OS;^>L%bc&mk`I%Hd$>S=XmB+ zN-i25Z9Luw33XKAC}0lHkC4EUtj+n#rC$?*wG)swhX(!|H;Y+>P&F$vyc95=CE~9!THvn(c4; zq`6gueVNq;a?Nr=Lb$>6aHG)~Fg|Ir$oI?|Hpvah%g`C5B9Sb-szPeFOIUcPj|q5w z3?Uw9c(wx2`G7rUrdj&kU_n0M?ks$fhv@^@qwWz787N+`i&6Vf8dSo10|-B33ZxT? zd0EY!c0i=EP_};W@$@bBK4R@>_DD!k9$g_v4^vmpP4Or`iHSbdkbGs(ifFCxa0*Oq zzVf}?@=g#+#RdzfG7`QefEfI7kc*JRL!(L%G6;51laeP56A!^b@x0Fe`}3tXv&Byg zzZ=ZQ#w#Fvp3w^%oerlf^w_4?qK{*Wq21T(`Wwd9GHMF#jvTZL>o#?R%NhbpsiB91 zfa>^-snw6!(U-c+5Pp3><%?k2dhhr`L?;yLp3N!ZI>yi~G-)sT#FG^`-qMFVYS#cG z{d@!ehm%$a;J`p zal&L#r$Cb~{}$J5B3|ku9!D1*+K$KAFpsR009(H1S*3+rB48C7&?!|~PDw&_-5-W9 znyaf4d*CgxWZxK6;L7BaNUU1=V1SEU8eiv7Oeay0b|BeBO!pQqY$0ByczVc5oQXFI ze&3d4RFig~tQ(gsej>!ECUl3Ds8cO;XWR(N7wcunC?|c#qZ?QKGHjF+bP%lcCXX9O zOGm2v7&$s?5!dW3QT0B2U8)rjDO7|WIs~rC^k$iyW8<&d}m#uh;?kxV~ zNvwNMf>}lSnn*XgJWj029hbG$JcEqU36$U5d0lK~bB&GGq(Atxq(l_ICThdz+?9K< zxrMJ;;^7^7DT~oE`mKz7IZF;^y?PIucOmp_?LL<7k?oeIdo8{sbQ_oQvsC8e07gv3 zC-PNSl2Jwa4qZ2n?WU->D;ayRYETlzZ%D~>q6o!IOIi{d{6YunXa=khatGs>yCU^*s<;D7 zrj55_&KC4@$vG*Hi$8B#U6UDT!@ASFpU^qW9WpKu`>blq>=sAIG^b1aQWa@SO-+>! zJkQ-9N-WJ5cr(e_RFk)$*DM32B2}h*v17=u-<|=WtY(`94S2cD%pJOgi+0mJiG>4f zPN}$xN13r#=ZyVyH%cUH{#0SF4d4sothuhVPJ7FPUK<3G&JHN;MZy){IcP|qijft} zmlhG4U>LCdG#jj=bP>GmSiS0*S10@J2@Bmh167GDk5boi3&te9t9*c`YNfelzTRy> z5ObO&08eqQ*EgZ0wtVc_d1{O9UpQkT!$sTsHvv-U-<}};XS>>ea7ICA0|Tpna*_T& zl=0hq-BD8&?W>7eGSp#jgscjC8EDwqYP=4)mBJd3$(}?>c^Lfp) z^0BgUx%ugJ+}GzX#1GRO9YkKg*^br@m9S&S)t9u?>Exv4h&ts^bO4nJFR${X$^B6S z>Lf-IQh@Hxf(~@3)gUGIcv3l`otFt~YD-dETS8X4Zdw~FOJbUKTU<(Ndy;xuD>cCp zD7>FJN7$i=IG9^0fIO8~Q?Sf8D!lKdT z!#7#IL7_ zRm`5D!NwZtwm5dUU#c}2XT#XKn5VBi&dqkU%G*q4u%6$?!z&=^=h$j6m4;{*9zhNH zQtVC{!1`d}hCKY|C81|U=ZUekFUW9uQV4Q*)-xuQJ6E7zpTko_2qJ1^RRT`mleHih z1&AZuYz7IMkkYOJPbyD~waG~MSH#Mbj5&K4Z4qrERoeZc;1abiOC6)SN7+CH4aQ-H z7MEamW0K*Q43DVbMwtO1O0)wiIW_eL@Em^}8;H2eSG?<sC0JkY-FNB3 z{!kgI@nRV3tsaN5PEULNnbDKlnV7zE62P9j3rvc+XTc-P!?+iDi GSI+3+|Pw& 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 + + + + + + + + + + + + + + + + + + + + diff --git a/android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java b/android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java new file mode 100644 index 00000000..6d7c49d6 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/BluetoothCommunication.java @@ -0,0 +1,105 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.core; + +import java.io.IOException; +import java.util.Set; +import java.util.UUID; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.os.Handler; +import android.os.Message; +import android.provider.SyncStateContract.Constants; +import android.support.v4.app.FragmentActivity; +import android.util.Log; + +public class BluetoothCommunication extends Thread { + public static final int BT_MESSAGE_READ = 0; + public static final int BT_SOCKET_CLOSED = 1; + public static final int BT_NO_ADAPTER = 2; + private final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); // Standard SerialPortService ID + + private BluetoothSocket btSocket; + private BluetoothDevice btDevice; + private BluetoothAdapter btAdapter; + private Handler btHandler; + private volatile boolean isCancel; + + public BluetoothCommunication(Handler handler) { + btHandler = handler; + isCancel = false; + } + + void findBT(String deviceName) throws IOException { + btAdapter = BluetoothAdapter.getDefaultAdapter(); + + if (btAdapter == null) { + btHandler.obtainMessage(BluetoothCommunication.BT_NO_ADAPTER).sendToTarget(); + return; + } + + Set pairedDevices = btAdapter.getBondedDevices(); + + for (BluetoothDevice device : pairedDevices) { + // check if we can found bluetooth device name in the pairing list + if (device.getName().equals(deviceName)) { + btDevice = device; + + // Get a BluetoothSocket to connect with the given BluetoothDevice + btSocket = btDevice.createRfcommSocketToServiceRecord(uuid); + return; + } + } + + throw new IOException("Bluetooth device not found"); + } + + public void run() { + while (!isCancel) { + try { + if (!btSocket.isConnected()) { + // Connect the device through the socket. This will block + // until it succeeds or throws an exception + btSocket.connect(); + } + + // Bluetooth connection was successful + Log.d("BluetoothCommunication", "Bluetooth connection successful established!"); + BluetoothConnectedThread btConnectThread = new BluetoothConnectedThread(btSocket, btHandler); + btConnectThread.start(); + return; + + } catch (IOException connectException) { + try { + sleep(4000); + } catch (InterruptedException e) { + Log.e("BluetoothCommuncation", "Sleep error " + e.getMessage()); + } + } + + } + } + + public void cancel() { + try { + btSocket.close(); + isCancel = true; + } catch (IOException e) { } + } +} \ No newline at end of file diff --git a/android_app/app/src/main/java/com/health/openscale/core/BluetoothConnectedThread.java b/android_app/app/src/main/java/com/health/openscale/core/BluetoothConnectedThread.java new file mode 100644 index 00000000..903f1e97 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/BluetoothConnectedThread.java @@ -0,0 +1,83 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ +package com.health.openscale.core; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import android.bluetooth.BluetoothSocket; +import android.os.Handler; +import android.util.Log; + +public class BluetoothConnectedThread extends Thread { + private BluetoothSocket btSocket; + private InputStream btInStream; + private OutputStream btOutStream; + private Handler btHandler; + + public BluetoothConnectedThread(BluetoothSocket socket, Handler handler) { + btSocket = socket; + btHandler = handler; + + // Get the input and output bluetooth streams + try { + btInStream = socket.getInputStream(); + btOutStream = socket.getOutputStream(); + } catch (IOException e) { + Log.e("BluetoothConnectedThread", "Can't get bluetooth input or output stream " + e.getMessage()); + } + } + + public void run() { + final StringBuilder btLine = new StringBuilder(); + + // Keep listening to the InputStream until an exception occurs (e.g. device partner goes offline) + while (true) { + try { + // stream read is a blocking method + char btChar = (char)btInStream.read(); + + btLine.append(btChar); + + if (btLine.charAt(btLine.length()-1) == '\n'){ + btHandler.obtainMessage(BluetoothCommunication.BT_MESSAGE_READ, btLine.toString()).sendToTarget(); + + btLine.setLength(0); + } + + } catch (IOException e) { + cancel(); + btHandler.obtainMessage(BluetoothCommunication.BT_SOCKET_CLOSED).sendToTarget(); + return; + } + } + } + + public void write(byte[] bytes) { + try { + btOutStream.write(bytes); + } catch (IOException e) { } + } + + public void cancel() { + try { + btSocket.close(); + } catch (IOException e) { + Log.e("BluetoothConnectedThread", "Error while closing bluetooth socket " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java new file mode 100644 index 00000000..d59db68d --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -0,0 +1,262 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.core; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +public class OpenScale { + + private static OpenScale instance; + + private ScaleDatabase scaleDB; + private ArrayList scaleDBEntries; + + private BluetoothCommunication btCom; + private String btDeviceName; + + private SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm"); + + private OpenScale(Context con) { + scaleDB = new ScaleDatabase(con); + scaleDBEntries = scaleDB.getAllDBEntries(); + } + + public static OpenScale getInstance(Context con) { + if (instance == null) { + instance = new OpenScale(con); + } + + return instance; + } + + public ArrayList getScaleDBEntries() { + return scaleDBEntries; + } + + public void addScaleData(String date_time, float weight, float fat, + float water, float muscle) { + ScaleData scaleData = new ScaleData(); + + try { + scaleData.date_time = dateTimeFormat.parse(date_time); + scaleData.weight = weight; + scaleData.fat = fat; + scaleData.water = water; + scaleData.muscle = muscle; + } catch (ParseException e) { + Log.e("OpenScale", "Can't parse date time string while adding to the database"); + } + + scaleDB.insertEntry(scaleData); + + scaleDBEntries = scaleDB.getAllDBEntries(); + } + + public void importData(String filename) throws IOException { + File file = new File(filename); + + FileInputStream inputStream = new FileInputStream(file); + + InputStreamReader inputReader = new InputStreamReader(inputStream); + BufferedReader csvReader = new BufferedReader(inputReader); + + String line = csvReader.readLine(); + + try { + while (line != null) { + String csvField[] = line.split(","); + + ScaleData newScaleData = new ScaleData(); + + newScaleData.date_time = dateTimeFormat.parse(csvField[0]); + newScaleData.weight = Float.parseFloat(csvField[1]); + newScaleData.fat = Float.parseFloat(csvField[2]); + newScaleData.water = Float.parseFloat(csvField[3]); + newScaleData.muscle = Float.parseFloat(csvField[4]); + + scaleDB.insertEntry(newScaleData); + + line = csvReader.readLine(); + } + + } catch (ParseException e) { + throw new IOException("Can't parse date format. Please set the date time format as (e.g. 31.10.2014 05:23)"); + } + + scaleDBEntries = scaleDB.getAllDBEntries(); + + csvReader.close(); + inputReader.close(); + } + + public void exportData(String filename) throws IOException { + File file = new File(filename); + file.createNewFile(); + + FileOutputStream outputStream = new FileOutputStream(file); + + OutputStreamWriter csvWriter = new OutputStreamWriter(outputStream); + + for (ScaleData scaleData : scaleDBEntries) { + csvWriter.append(dateTimeFormat.format(scaleData.date_time) + ","); + csvWriter.append(Float.toString(scaleData.weight) + ","); + csvWriter.append(Float.toString(scaleData.fat) + ","); + csvWriter.append(Float.toString(scaleData.water) + ","); + csvWriter.append(Float.toString(scaleData.muscle)); + csvWriter.append("\n"); + } + + csvWriter.close(); + outputStream.close(); + } + + public void deleteAllDBEntries() { + scaleDB.deleteAllEntries(); + + scaleDBEntries = scaleDB.getAllDBEntries(); + } + + public void startBluetoothServer(String deviceName) { + Log.d("OpenScale", "Bluetooth Server started! I am searching for device ..."); + + btCom = new BluetoothCommunication(btHandler); + btDeviceName = deviceName; + + try { + btCom.findBT(btDeviceName); + btCom.start(); + } catch (IOException e) { + Log.e("OpenScale", "Error " + e.getMessage()); + } + } + + public void stopBluetoothServer() { + Log.d("OpenScale", "Bluetooth Server stopped!"); + + if (btCom != null) { + btCom.cancel(); + } + } + + /** + * The Handler that gets information back from the BluetoothChatService + */ + private final Handler btHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + + switch (msg.what) { + case BluetoothCommunication.BT_MESSAGE_READ: + String line = (String) msg.obj; + + parseBtString(line); + break; + case BluetoothCommunication.BT_SOCKET_CLOSED: + scaleDBEntries = scaleDB.getAllDBEntries(); + + Log.i("OpenScale", "Socket closed! Restarting socket "); + + startBluetoothServer(btDeviceName); + break; + case BluetoothCommunication.BT_NO_ADAPTER: + Log.e("OpenScale", "No bluetooth adapter found!"); + break; + } + } + }; + + public void parseBtString(String btString) { + btString = btString.substring(0, btString.length() - 1); // delete newline '\n' of the string + + if (btString.charAt(0) != '$' && btString.charAt(2) != '$') { + Log.e("OpenScale", "Parse error of bluetooth string. String has not a valid format"); + return; + } + + String btMsg = btString.substring(3, btString.length()); // message string + + switch (btString.charAt(1)) { + case 'I': + Log.i("OpenScale", "MCU Information: " + btMsg); + break; + case 'E': + Log.e("OpenScale", "MCU Error: " + btMsg); + break; + case 'S': + Log.i("OpenScale", "MCU stored data size: " + btMsg); + break; + case 'D': + ScaleData scaleBtData = new ScaleData(); + + String[] csvField = btMsg.split(","); + + try { + int checksum = 0; + + checksum ^= Integer.parseInt(csvField[1]); + checksum ^= Integer.parseInt(csvField[2]); + checksum ^= Integer.parseInt(csvField[3]); + checksum ^= Integer.parseInt(csvField[4]); + checksum ^= Integer.parseInt(csvField[5]); + checksum ^= (int)Float.parseFloat(csvField[6]); + checksum ^= (int)Float.parseFloat(csvField[7]); + checksum ^= (int)Float.parseFloat(csvField[8]); + checksum ^= (int)Float.parseFloat(csvField[9]); + + int btChecksum = Integer.parseInt(csvField[10]); + + if (checksum == btChecksum) { + scaleBtData.id = Long.parseLong(csvField[0]); + String date_string = csvField[1] + "/" + csvField[2] + "/" + csvField[3] + "/" + csvField[4] + "/" + csvField[5]; + scaleBtData.date_time = new SimpleDateFormat("yyyy/MM/dd/HH/mm").parse(date_string); + + scaleBtData.weight = Float.parseFloat(csvField[6]); + scaleBtData.fat = Float.parseFloat(csvField[7]); + scaleBtData.water = Float.parseFloat(csvField[8]); + scaleBtData.muscle = Float.parseFloat(csvField[9]); + + Log.i("OpenScale", "MCU Data: " + scaleBtData); + scaleDB.insertEntry(scaleBtData); + } else { + Log.e("OpenScale", "Error calculated checksum (" + checksum + ") and received checksum (" + btChecksum + ") is different"); + } + } catch (ParseException e) { + Log.e("OpenScale", "Error while decoding bluetooth date string (" + e.getMessage() + ")"); + } catch (NumberFormatException e) { + Log.e("OpenScale", "Error while decoding a number of bluetooth string (" + e.getMessage() + ")"); + } + break; + default: + Log.e("OpenScale", "Error unknown MCU command"); + break; + } + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleData.java b/android_app/app/src/main/java/com/health/openscale/core/ScaleData.java new file mode 100644 index 00000000..43329f95 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/ScaleData.java @@ -0,0 +1,36 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.core; + +import java.util.Date; + +import android.util.Log; + +public class ScaleData { + public long id; + public Date date_time; + public float weight; + public float fat; + public float water; + public float muscle; + + @Override + public String toString() + { + return "ID : " + id + " DATE_TIME: " + date_time.toString() + " WEIGHT: " + weight + " FAT: " + fat + " WATER: " + water + " MUSCLE: " + muscle; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java new file mode 100644 index 00000000..2384bbb1 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/ScaleDatabase.java @@ -0,0 +1,160 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.core; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteDatabase.CursorFactory; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +public class ScaleDatabase extends SQLiteOpenHelper { + private static final int DATABASE_VERSION = 1; + private static final String DATABASE_NAME = "openScaleDatabase.db"; + + private static final String TABLE_NAME = "scaledata"; + private static final String COLUMN_NAME_ID = "id"; + private static final String COLUMN_NAME_DATE_TIME = "date_time"; + private static final String COLUMN_NAME_WEIGHT = "weight"; + private static final String COLUMN_NAME_FAT = "fat"; + private static final String COLUMN_NAME_WATER = "water"; + private static final String COLUMN_NAME_MUSCLE = "muscle"; + + private static final String SQL_CREATE_ENTRIES = + "CREATE TABLE " + TABLE_NAME + " (" + + COLUMN_NAME_ID + " INTEGER PRIMARY KEY," + + COLUMN_NAME_DATE_TIME + " TEXT UNIQUE," + + COLUMN_NAME_WEIGHT + " REAL," + + COLUMN_NAME_FAT + " REAL," + + COLUMN_NAME_WATER + " REAL," + + COLUMN_NAME_MUSCLE + " REAL" + + ")"; + + private static final String SQL_DELETE_ENTRIES = + "DROP TABLE IF EXISTS " + TABLE_NAME; + + private SimpleDateFormat formatDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + + public ScaleDatabase(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(SQL_CREATE_ENTRIES); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + db.execSQL(SQL_DELETE_ENTRIES); + onCreate(db); + } + + public void deleteAllEntries() { + SQLiteDatabase db = getWritableDatabase(); + + db.delete(TABLE_NAME, null, null); + } + + public void insertEntry(ScaleData scaleData) { + SQLiteDatabase db = getWritableDatabase(); + + // Create a new map of values, where column names are the keys + ContentValues values = new ContentValues(); + values.put(COLUMN_NAME_DATE_TIME, formatDateTime.format(scaleData.date_time)); + values.put(COLUMN_NAME_WEIGHT, scaleData.weight); + values.put(COLUMN_NAME_FAT, scaleData.fat); + values.put(COLUMN_NAME_WATER, scaleData.water); + values.put(COLUMN_NAME_MUSCLE, scaleData.muscle); + + // Insert the new row, returning the primary key value of the new row + long newRowId = db.insert(TABLE_NAME, null, values); + + if (newRowId == -1) { + Log.e("ScaleDatabase", "An error occured while inserting a new entry into the scale database"); + } + } + + public ArrayList getAllDBEntries() { + SQLiteDatabase db = getReadableDatabase(); + ArrayList scaleDBEntries = new ArrayList(); + + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + COLUMN_NAME_ID, + COLUMN_NAME_DATE_TIME, + COLUMN_NAME_WEIGHT, + COLUMN_NAME_FAT, + COLUMN_NAME_WATER, + COLUMN_NAME_MUSCLE + }; + + // How you want the results sorted in the resulting Cursor + String sortOrder = COLUMN_NAME_DATE_TIME + " DESC"; + + Cursor cursorScaleDB = db.query( + TABLE_NAME, // The table to query + projection, // The columns to return + null, // The columns for the WHERE clause + null, // The values for the WHERE clause + null, // don't group the rows + null, // don't filter by row groups + sortOrder // The sort order + ); + + try { + cursorScaleDB.moveToFirst(); + + while (!cursorScaleDB.isAfterLast()) { + ScaleData dataEntry = new ScaleData(); + + dataEntry.id = cursorScaleDB.getLong(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_ID)); + String date_time = cursorScaleDB.getString(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_DATE_TIME)); + dataEntry.weight = cursorScaleDB.getFloat(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_WEIGHT)); + dataEntry.fat = cursorScaleDB.getFloat(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_FAT)); + dataEntry.water = cursorScaleDB.getFloat(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_WATER)); + dataEntry.muscle = cursorScaleDB.getFloat(cursorScaleDB.getColumnIndexOrThrow(COLUMN_NAME_MUSCLE)); + + Date date = formatDateTime.parse(date_time); + + dataEntry.date_time = date; + + scaleDBEntries.add(dataEntry); + //Log.d("ScaleDatabase", dataEntry.toString()); + + cursorScaleDB.moveToNext(); + } + } catch (ParseException ex) { + Log.e("ScaleDatabase", "Can't parse the date time string: " + ex.getMessage()); + } + catch ( IllegalArgumentException ex) { + Log.e("ScaleDatabase", "Illegal argument while reading from scale database: " + ex.getMessage()); + } + + + return scaleDBEntries; + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java b/android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java new file mode 100644 index 00000000..f826ea62 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/FragmentUpdateListener.java @@ -0,0 +1,25 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.gui; + +import java.util.ArrayList; + +import com.health.openscale.core.ScaleData; + +public interface FragmentUpdateListener { + public void updateOnView(ArrayList scaleDBEntries); +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java new file mode 100644 index 00000000..81962caa --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/GraphFragment.java @@ -0,0 +1,119 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.gui; + +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.List; + +import lecho.lib.hellocharts.model.Axis; +import lecho.lib.hellocharts.model.AxisValue; +import lecho.lib.hellocharts.model.Line; +import lecho.lib.hellocharts.model.LineChartData; +import lecho.lib.hellocharts.model.PointValue; +import lecho.lib.hellocharts.view.LineChartView; +import android.graphics.Color; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.health.openscale.R; +import com.health.openscale.core.ScaleData; + +public class GraphFragment extends Fragment implements FragmentUpdateListener { + private View graphView; + private LineChartView chartView; + + public GraphFragment() { + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + graphView = inflater.inflate(R.layout.fragment_graph, container, false); + + chartView = (LineChartView) graphView.findViewById(R.id.data_chart); + + return graphView; + } + + @Override + public void updateOnView(ArrayList scaleDBEntries) + { + if (scaleDBEntries.isEmpty()) { + LineChartData data = new LineChartData(); + chartView.setLineChartData(data); + + return; + } + + List axisValues = new ArrayList(); + List valuesWeight = new ArrayList(); + List valuesFat = new ArrayList(); + List valuesWater = new ArrayList(); + List valuesMuscle = new ArrayList(); + List lines = new ArrayList(); + + + for(ScaleData scaleEntry: scaleDBEntries) + { + valuesWeight.add(new PointValue(scaleEntry.date_time.getTime(), scaleEntry.weight)); + valuesFat.add(new PointValue(scaleEntry.date_time.getTime(), scaleEntry.fat)); + valuesWater.add(new PointValue(scaleEntry.date_time.getTime(), scaleEntry.water)); + valuesMuscle.add(new PointValue(scaleEntry.date_time.getTime(), scaleEntry.muscle)); + + axisValues.add(new AxisValue(scaleEntry.date_time.getTime(), DateFormat.getDateInstance(DateFormat.SHORT).format(scaleEntry.date_time).toCharArray())); + } + + Line lineWeight = new Line(valuesWeight).setColor(Color.GREEN); + Line lineFat = new Line(valuesFat).setColor(Color.RED); + Line lineWater = new Line(valuesWater).setColor(Color.BLUE); + Line lineMuscle = new Line(valuesMuscle).setColor(Color.GRAY); + + lines.add(lineWeight); + lines.add(lineFat); + lines.add(lineWater); + lines.add(lineMuscle); + + lineWeight.setHasLabels(true); + lineWeight.setHasLabelsOnlyForSelected(true); + lineFat.setHasLabelsOnlyForSelected(true); + + LineChartData data = new LineChartData(); + + Axis axisX = new Axis(axisValues); + Axis axisY = new Axis(); + + axisY.setHasLines(true); + + axisX.setName("Zeit"); + axisY.setName("Wert"); + + axisX.setTextColor(Color.BLACK); + axisY.setTextColor(Color.BLACK); + + data.setAxisXBottom(axisX); + data.setAxisYLeft(axisY); + + data.setLines(lines); + + chartView.setLineChartData(data); + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java new file mode 100644 index 00000000..d76aa4af --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java @@ -0,0 +1,205 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ + +package com.health.openscale.gui; + +import java.util.Locale; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.app.FragmentTransaction; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; + +import com.health.openscale.R; +import com.health.openscale.core.OpenScale; + + +public class MainActivity extends ActionBarActivity implements + ActionBar.TabListener { + + /** + * The {@link android.support.v4.view.PagerAdapter} that will provide + * fragments for each of the sections. We use a {@link FragmentPagerAdapter} + * derivative, which will keep every loaded fragment in memory. If this + * becomes too memory intensive, it may be best to switch to a + * {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + private SectionsPagerAdapter mSectionsPagerAdapter; + + /** + * The {@link ViewPager} that will host the section contents. + */ + private ViewPager mViewPager; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if(prefs.getBoolean("btEnable", true)) { + Log.i("ASD", "BT TRZE"); + String deviceName = prefs.getString("btDeviceName", "openScale"); + OpenScale.getInstance(getApplicationContext()).startBluetoothServer(deviceName); + } + + // Set up the action bar. + final ActionBar actionBar = getSupportActionBar(); + actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + + // Create the adapter that will return a fragment for each of the three + // primary sections of the activity. + mSectionsPagerAdapter = new SectionsPagerAdapter( + getSupportFragmentManager(), this); + + // Set up the ViewPager with the sections adapter. + mViewPager = (ViewPager) findViewById(R.id.pager); + mViewPager.setAdapter(mSectionsPagerAdapter); + + // When swiping between different sections, select the corresponding + // tab. We can also use ActionBar.Tab#select() to do this if we have + // a reference to the Tab. + mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + actionBar.setSelectedNavigationItem(position); + + FragmentUpdateListener fragment = (FragmentUpdateListener) mSectionsPagerAdapter.instantiateItem(mViewPager, position); + if (fragment != null) { + fragment.updateOnView(OpenScale.getInstance(mViewPager.getContext()).getScaleDBEntries()); + } + } + }); + + // For each of the sections in the app, add a tab to the action bar. + for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { + // Create a tab with text corresponding to the page title defined by + // the adapter. Also specify this Activity object, which implements + // the TabListener interface, as the callback (listener) for when + // this tab is selected. + actionBar.addTab(actionBar.newTab() + .setText(mSectionsPagerAdapter.getPageTitle(i)) + .setTabListener(this)); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + if (id == R.id.action_settings) { + Intent intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onTabSelected(ActionBar.Tab tab, + FragmentTransaction fragmentTransaction) { + // When the given tab is selected, switch to the corresponding page in + // the ViewPager. + mViewPager.setCurrentItem(tab.getPosition()); + } + + @Override + public void onTabUnselected(ActionBar.Tab tab, + FragmentTransaction fragmentTransaction) { + } + + @Override + public void onTabReselected(ActionBar.Tab tab, + FragmentTransaction fragmentTransaction) { + } + + /** + * A {@link FragmentPagerAdapter} that returns a fragment corresponding to + * one of the sections/tabs/pages. + */ + public class SectionsPagerAdapter extends FragmentPagerAdapter { + + private OverviewFragment overviewFrag; + private GraphFragment graphFrag; + private TableFragment tableFrag; + + public SectionsPagerAdapter(FragmentManager fm, Context con) { + super(fm); + + overviewFrag = new OverviewFragment(); + graphFrag = new GraphFragment(); + tableFrag = new TableFragment(); + } + + @Override + public Fragment getItem(int position) { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class + // below). + + switch (position) { + case 0: + return overviewFrag; + case 1: + return graphFrag; + case 2: + return tableFrag; + } + + return null; + } + + @Override + public int getCount() { + return 3; + } + + @Override + public CharSequence getPageTitle(int position) { + Locale l = Locale.getDefault(); + switch (position) { + case 0: + return getString(R.string.title_overview).toUpperCase(l); + case 1: + return getString(R.string.title_graph).toUpperCase(l); + case 2: + return getString(R.string.title_frag).toUpperCase(l); + } + return null; + } + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/NewEntryActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/NewEntryActivity.java new file mode 100644 index 00000000..1f537282 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/NewEntryActivity.java @@ -0,0 +1,198 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ +package com.health.openscale.gui; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import android.app.Activity; +import android.app.DatePickerDialog; +import android.app.TimePickerDialog; +import android.content.Context; +import android.os.Bundle; +import android.support.v4.app.FragmentTransaction; +import android.view.View; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.EditText; +import android.widget.TimePicker; + +import com.health.openscale.R; +import com.health.openscale.core.OpenScale; + +public class NewEntryActivity extends Activity { + + private EditText txtWeight; + private EditText txtFat; + private EditText txtWater; + private EditText txtMuscle; + private EditText txtDate; + private EditText txtTime; + + private SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy"); + private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); + + private Context context; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_newentry); + context = this; + + txtWeight = (EditText) findViewById(R.id.txtWeight); + txtFat = (EditText) findViewById(R.id.txtFat); + txtWater = (EditText) findViewById(R.id.txtWater); + txtMuscle = (EditText) findViewById(R.id.txtMuscle); + txtDate = (EditText) findViewById(R.id.txtDate); + txtTime = (EditText) findViewById(R.id.txtTime); + Button btnDateSet = (Button) findViewById(R.id.btnDateSet); + Button btnTimeSet = (Button) findViewById(R.id.btnTimeSet); + + findViewById(R.id.btnAdd).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + btnOnClickAdd(); + } + }); + + findViewById(R.id.btnCancel).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + btnOnClickCancel(); + } + }); + + btnDateSet.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + Calendar cal = Calendar.getInstance(); + DatePickerDialog datePicker = new DatePickerDialog(context, datePickerListener, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + datePicker.show(); + } + }); + + btnTimeSet.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + Calendar cal = Calendar.getInstance(); + TimePickerDialog timePicker = new TimePickerDialog(context, timePickerListener, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), true); + timePicker.show(); + } + }); + + txtDate.setText(dateFormat.format(new Date())); + txtTime.setText(timeFormat.format(new Date())); + } + + private boolean validateInput() + { + boolean validate = true; + + if( txtWeight.getText().toString().length() == 0 ) + { + txtWeight.setError("Weight value ist required!"); + validate = false; + } else if( !(Float.valueOf(txtWeight.getText().toString()) >= 0 && Float.valueOf(txtWeight.getText().toString()) <= 300) ) + { + txtWeight.setError("Value must be in range from 0 to 300!"); + validate = false; + } + + if( txtFat.getText().toString().length() == 0 ) + { + txtFat.setError("Fat value ist required!"); + validate = false; + } else if(!isInRange(txtFat.getText().toString())) + { + txtFat.setError("Value must be in range from 0 to 100"); + validate = false; + } + + + if( txtWater.getText().toString().length() == 0 ) + { + txtWater.setError("Water value ist required!"); + validate = false; + } else if(!isInRange(txtWater.getText().toString())) + { + txtWater.setError("Value must be in range from 0 to 100"); + validate = false; + } + + if( txtMuscle.getText().toString().length() == 0 ) + { + txtMuscle.setError("Muscle value ist required!"); + validate = false; + } else if(!isInRange(txtMuscle.getText().toString())) + { + txtMuscle.setError("Value must be in range from 0 to 100"); + validate = false; + } + + return validate; + } + + private boolean isInRange(String value) + { + if (value.length() == 0) + return false; + + float val = Float.valueOf(value); + + if (val >= 0 && val <= 100) + return true; + + return false; + } + + public void btnOnClickAdd() + { + if (validateInput()) + { + OpenScale openScale = OpenScale.getInstance(context); + + float weight = Float.valueOf(txtWeight.getText().toString()); + float fat = Float.valueOf(txtFat.getText().toString()); + float water = Float.valueOf(txtWater.getText().toString()); + float muscle = Float.valueOf(txtMuscle.getText().toString()); + + String date = txtDate.getText().toString(); + String time = txtTime.getText().toString(); + + openScale.addScaleData(date + " " + time, weight, fat, water, muscle); + + finish(); + } + } + + public void btnOnClickCancel() + { + finish(); + } + + private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) { + txtDate.setText(String.format("%02d.%02d.%04d", selectedDay, selectedMonth+1, selectedYear)); + } + }; + + private TimePickerDialog.OnTimeSetListener timePickerListener = new TimePickerDialog.OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + txtTime.setText(String.format("%02d:%02d", hourOfDay, minute)); + } + }; + +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java new file mode 100644 index 00000000..5cb3ac66 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/OverviewFragment.java @@ -0,0 +1,124 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ +package com.health.openscale.gui; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; + +import lecho.lib.hellocharts.model.ArcValue; +import lecho.lib.hellocharts.model.PieChartData; +import lecho.lib.hellocharts.util.Utils; +import lecho.lib.hellocharts.view.PieChartView; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.health.openscale.R; +import com.health.openscale.core.OpenScale; +import com.health.openscale.core.ScaleData; + +public class OverviewFragment extends Fragment implements FragmentUpdateListener { + private View overviewView; + private PieChartView pieChart; + private TextView txtAvgWeight; + private TextView txtAvgFat; + private TextView txtAvgWater; + private TextView txtAvgMuscle; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + overviewView = inflater.inflate(R.layout.fragment_overview, container, false); + + pieChart = (PieChartView) overviewView.findViewById(R.id.data_pie_chart); + txtAvgWeight = (TextView) overviewView.findViewById(R.id.txtAvgWeight); + txtAvgFat = (TextView) overviewView.findViewById(R.id.txtAvgFat); + txtAvgWater = (TextView) overviewView.findViewById(R.id.txtAvgWater); + txtAvgMuscle = (TextView) overviewView.findViewById(R.id.txtAvgMuscle); + + overviewView.findViewById(R.id.btnInsertData).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + btnOnClickInsertData(); + } + }); + + updateOnView(OpenScale.getInstance(overviewView.getContext()).getScaleDBEntries()); + + return overviewView; + } + + @Override + public void updateOnView(ArrayList scaleDBEntries) + { + List arcValues = new ArrayList(); + + if (scaleDBEntries.isEmpty()) { + return; + } + + ScaleData lastEntry = scaleDBEntries.get(0); + + arcValues.add(new ArcValue((float) lastEntry.fat, Utils.COLOR_ORANGE)); + arcValues.add(new ArcValue((float) lastEntry.water, Utils.COLOR_BLUE)); + arcValues.add(new ArcValue((float) lastEntry.muscle, Utils.COLOR_GREEN)); + + PieChartData pieChartData = new PieChartData(arcValues); + pieChartData.setHasLabels(true); + pieChartData.setHasCenterCircle(true); + pieChartData.setCenterText1(Float.toString(lastEntry.weight) + " kg"); + pieChartData.setCenterText1FontSize(35); + pieChartData.setCenterText2(new SimpleDateFormat("dd. MMM yyyy (EE)").format(lastEntry.date_time)); + pieChartData.setCenterText2FontSize(15); + + pieChart.setPieChartData(pieChartData); + + double avgWeight = 0; + double avgFat = 0; + double avgWater = 0; + double avgMuscle = 0; + + for (ScaleData scaleData : scaleDBEntries) + { + avgWeight += scaleData.weight; + avgFat += scaleData.fat; + avgWater += scaleData.water; + avgMuscle += scaleData.muscle; + } + + avgWeight = avgWeight / scaleDBEntries.size(); + avgFat = avgFat / scaleDBEntries.size(); + avgWater = avgWater / scaleDBEntries.size(); + avgMuscle = avgMuscle / scaleDBEntries.size(); + + txtAvgWeight.setText(String.format( "%.1f kg", avgWeight)); + txtAvgFat.setText(String.format( "%.1f %%", avgFat)); + txtAvgWater.setText(String.format( "%.1f %%", avgWater)); + txtAvgMuscle.setText(String.format( "%.1f %%", avgMuscle)); + } + + public void btnOnClickInsertData() + { + Intent intent = new Intent(overviewView.getContext(), NewEntryActivity.class); + startActivity(intent); + } + +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java new file mode 100644 index 00000000..3448c14a --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/SettingsActivity.java @@ -0,0 +1,114 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ +package com.health.openscale.gui; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.MultiSelectListPreference; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceGroup; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.health.openscale.R; +import com.health.openscale.core.OpenScale; + +public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { + +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences); + initSummary(getPreferenceScreen()); +} + +@Override +protected void onResume() { + super.onResume(); + // Set up a listener whenever a key changes + getPreferenceScreen().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); +} + +@Override +protected void onPause() { + super.onPause(); + // Unregister the listener whenever a key changes + getPreferenceScreen().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); +} + +@Override +public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + updatePrefSummary(findPreference(key)); + + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + + if(prefs.getBoolean("btEnable", true)) + { + String deviceName = prefs.getString("btDeviceName", "openScale"); + OpenScale.getInstance(getApplicationContext()).startBluetoothServer(deviceName); + } else { + OpenScale.getInstance(getApplicationContext()).stopBluetoothServer(); + } +} + +private void initSummary(Preference p) { + if (p instanceof PreferenceGroup) { + PreferenceGroup pGrp = (PreferenceGroup) p; + for (int i = 0; i < pGrp.getPreferenceCount(); i++) { + initSummary(pGrp.getPreference(i)); + } + } else { + updatePrefSummary(p); + } +} + +private void updatePrefSummary(Preference p) { + if (p instanceof ListPreference) { + ListPreference listPref = (ListPreference) p; + p.setSummary(listPref.getEntry()); + } + if (p instanceof EditTextPreference) { + EditTextPreference editTextPref = (EditTextPreference) p; + if (p.getTitle().toString().contains("assword")) + { + p.setSummary("******"); + } else { + p.setSummary(editTextPref.getText()); + } + } + if (p instanceof MultiSelectListPreference) { + EditTextPreference editTextPref = (EditTextPreference) p; + p.setSummary(editTextPref.getText()); + } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if(prefs.getBoolean("btEnable", true)) + { + findPreference("btDeviceName").setEnabled(true); + } else { + findPreference("btDeviceName").setEnabled(false); + } +} + +} diff --git a/android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java new file mode 100644 index 00000000..72535839 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/gui/TableFragment.java @@ -0,0 +1,224 @@ +/* Copyright (C) 2014 olie.xdev +* +* This program 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. +* +* This program 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 this program. If not, see +*/ +package com.health.openscale.gui; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Environment; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TableRow.LayoutParams; +import android.widget.TextView; +import android.widget.Toast; + +import com.health.openscale.R; +import com.health.openscale.core.OpenScale; +import com.health.openscale.core.ScaleData; + +public class TableFragment extends Fragment implements FragmentUpdateListener { + private View tableView; + private TableLayout tableDataView; + + public TableFragment() { + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + tableView = inflater.inflate(R.layout.fragment_table, container, false); + + tableDataView = (TableLayout) tableView.findViewById(R.id.tableDataView); + + tableView.findViewById(R.id.btnImportData).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + openImportDialog(); + } + }); + + tableView.findViewById(R.id.btnExportData).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + openExportDialog(); + } + }); + + tableView.findViewById(R.id.btnDeleteAll).setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + openDeleteAllDialog(); + } + }); + + return tableView; + } + + @Override + public void updateOnView(ArrayList scaleDBEntries) + { + TableRow headerRow = (TableRow) tableView.findViewById(R.id.tableHeader); + tableDataView.removeAllViews(); + tableDataView.addView(headerRow); + + for(ScaleData scaleEntry: scaleDBEntries) + { + TableRow dataRow = new TableRow(tableView.getContext()); + dataRow.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + + TextView dateTextView = new TextView(tableView.getContext()); + dateTextView.setText(new SimpleDateFormat("dd. MMM yyyy (EE)").format(scaleEntry.date_time)); + dateTextView.setPadding(5, 5, 5, 5); + dataRow.addView(dateTextView); + + TextView timeTextView = new TextView(tableView.getContext()); + timeTextView.setText(new SimpleDateFormat("HH:mm").format(scaleEntry.date_time)); + timeTextView.setPadding(5, 5, 5, 5); + dataRow.addView(timeTextView); + + TextView weightView = new TextView(tableView.getContext()); + weightView.setText(Float.toString(scaleEntry.weight)); + weightView.setPadding(5, 5, 5, 5); + dataRow.addView(weightView); + + TextView fatView = new TextView(tableView.getContext()); + fatView.setText(Float.toString(scaleEntry.fat)); + fatView.setPadding(5, 5, 5, 5); + dataRow.addView(fatView); + + TextView waterView = new TextView(tableView.getContext()); + waterView.setText(Float.toString(scaleEntry.water)); + waterView.setPadding(5, 5, 5, 5); + dataRow.addView(waterView); + + TextView muscleView = new TextView(tableView.getContext()); + muscleView.setText(Float.toString(scaleEntry.muscle)); + muscleView.setPadding(5, 5, 5, 5); + dataRow.addView(muscleView); + + tableDataView.addView(dataRow, new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + } + } + + public void openImportDialog() + { + AlertDialog.Builder filenameDialog = new AlertDialog.Builder(getActivity()); + + filenameDialog.setTitle("Set filename on /sdcard ..."); + + final EditText txtFilename = new EditText(tableView.getContext()); + txtFilename.setText("/openScale_data.csv"); + + filenameDialog.setView(txtFilename); + + filenameDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + boolean isError = false; + + try { + OpenScale.getInstance(tableView.getContext()).importData(Environment.getExternalStorageDirectory().getPath() + txtFilename.getText().toString()); + } catch (IOException e) { + Toast.makeText(tableView.getContext(), "Error importing " + e.getMessage(), Toast.LENGTH_SHORT).show(); + isError = true; + } + + if (!isError) { + Toast.makeText(tableView.getContext(), "Data imported from /sdcard" + txtFilename.getText().toString(), Toast.LENGTH_SHORT).show(); + updateOnView(OpenScale.getInstance(tableView.getContext()).getScaleDBEntries()); + } + } + }); + + filenameDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); + + + filenameDialog.show(); + } + + public void openExportDialog() + { + AlertDialog.Builder filenameDialog = new AlertDialog.Builder(getActivity()); + + filenameDialog.setTitle("Set filename on /sdcard ..."); + + final EditText txtFilename = new EditText(tableView.getContext()); + txtFilename.setText("/openScale_data.csv"); + + filenameDialog.setView(txtFilename); + + filenameDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + boolean isError = false; + + try { + OpenScale.getInstance(tableView.getContext()).exportData(Environment.getExternalStorageDirectory().getPath() + txtFilename.getText().toString()); + } catch (IOException e) { + Toast.makeText(tableView.getContext(), "Error exporting " + e.getMessage(), Toast.LENGTH_SHORT).show(); + isError = true; + } + + if (!isError) { + Toast.makeText(tableView.getContext(), "Data exported to /sdcard" + txtFilename.getText().toString(), Toast.LENGTH_SHORT).show(); + } + } + }); + + filenameDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); + + + filenameDialog.show(); + } + + public void openDeleteAllDialog() + { + AlertDialog.Builder deleteAllDialog = new AlertDialog.Builder(getActivity()); + + deleteAllDialog.setMessage("Do you really want to delete all database entries?"); + + deleteAllDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + OpenScale.getInstance(tableView.getContext()).deleteAllDBEntries(); + + Toast.makeText(tableView.getContext(), "All database entries deleted!", Toast.LENGTH_SHORT).show(); + updateOnView(OpenScale.getInstance(tableView.getContext()).getScaleDBEntries()); + } + }); + + deleteAllDialog.setNegativeButton("No", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); + + deleteAllDialog.show(); + } +} diff --git a/android_app/app/src/main/res/drawable/flat_selector.xml b/android_app/app/src/main/res/drawable/flat_selector.xml new file mode 100644 index 00000000..6e9fe6c4 --- /dev/null +++ b/android_app/app/src/main/res/drawable/flat_selector.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/android_app/app/src/main/res/drawable/ic_launcher.png b/android_app/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..ddd810cf15a573ecab13a69796941d6cd69e449d GIT binary patch literal 17493 zcmc(H`9GB18}MycC{$DwQ7S^KwHiVyp+u5pdO{IJ*|)iAB_WkOWlNi~O~}5CM3NX~ z8T;4=V~lV^L_t-_m|h_3YL_k~gvW2-RbO0)Wrqf&JXrO16?+FJ#0D;8+ z6*#slB^Y#y`Jc2j6C0EimESKF-_BHkAZ6&Jsj+QvFD=b0*W2+tsqtdv${?lxM#rT+ z2GS*07*{DZP_blgVcebPsbBX4xbNp61`DJ&~xYPL()!EYwi}Trmo%&%U*ZgHA zbYG+5Ibnd?|K}f3^E&fd${J{|(XFF`rqM)s2ohf{oplG@!eom>Ml;O~hw-dRXx@i+z(OTq+X@76M1(>t3wBByaUD6ihtFE8jAYnK%0ZBo=2y_eWG@ke5=ky0B0{k#ID|_7-c~P3u(3?^?nt z5orj@QsbsSrU-l?3ZZJ+O>)xW%7~#p@89mM4N4ZLZbMMyIe+fHe@N!%=L^p4HG(3$ zJLDp0V|lgIzPLuUqJ{^|U;(J^XV$3h^XTfJ6#Wsr(o-WN-vwi61naz%_r`ilCMM;l zoYI7<2;{L{nR#%>M9yl)0l#OKGO6CuzSAQa9n!pGW5kZ@1}`*^*6m&mwVm8MH|2E} zyZaY*cL6D3d|D?*MmW_J^35Jm^5azKX)nh&dC%{&GJzspgrbONjEyG03z~a()}9m= z$l8V2^&`jCm41mq8@;9H98S$7PX|s33j{tKaw`I~A}8x<4<;6g(h*SP7cqg1JX6?V zoAjpufu7wWP}X+DJudk0FH|pUJydHfBB1^7`@qFHy5JY131Pv4J+;5U7-huW6KB1I z{(DXw8hUjnvgsn1o_fj1TITM40rNBwy})^Gi$&^c- zLmIxT1VL+dLCoL99Kt>asCxgkzy0O>dB&zSQ>({ zo!7Qx6deGB%}7Jsk&8>(otXm!d+1-qmmEwzYwqz}Upf!ChsrslSqgiZjht!5=2?jC zL*YFZyj<$lbTBh80L3WWL@6>1c(3A1ru|9A0peOj<1anKrlnh%8|U=`2u=WZ>x-YpuW04xgoElcFnfwgW2 zmI=@1Y$IuG-C*+waeVuAvIQNdckC>>L3P4ms3s`7pKc&0k$OGKree+d_u)d2BW27! z=KIs-d0W%`t_K4mZGDLSeK~2x+l$txoG@lM-|zCzuJ#as59VmUwETj zhA;0n^?^{pN=|K_9O^zso@mXhDO-=8cQYLLV215ro#Td22n&3afvex@q**tjXOHN< z1T1ONU1Q$bz*elb&BtC9Z0#uD6VFjPt#fIzm27b?eVF}E?Pc^y4BP&ATea&)q~*6b zVzY|#qiJ)lA|<0~r60Z~Na?1%P(|J>`>8G$tr2~gVZPwK+(LFcSeuwW3OlB^aO7vv zll8p5(*u|K(Z^{RKc4T2+Zp<=uWQ^%K0agr?NB$RYC^>YxI=2g7urDPnC-mTIG1iGR`<0qCf~}u(uu7Cu+~rV;-#YPB zV%8{(aS#v*8NUXJdHFTNEJ6BF@l^S$jJ73%r@;xy+wY@_u)Su<@1NZK(6Z!tu zNX3tQ_Oz(la(-)``~& zV8v=&X3wF4ENmj1@U$g&;FS$(5`ehxhMh1=w1vE2^5%aC=Mpqk8P`Q?n^h(^2n0Hw z-Is9Eh)FBoUO15W^TwGGeYF0j0cHApEPN9iWU6sHin1vR_`~8yd-aSMuof-{OG8YW zkx*-%l1(u|^R%Fc;~ZA!Sgy!L31*xOPi2AhAbHhXKYU`YxH;h+gPOZoN=cGhZ4;2T z>%EZ8DD%4Xkn?)&)X^&O)f4UW)<2582T2E}hoA=7O)&CZeGuzSFQJaQ5J*!UUwb_k z2@`rvI2ezdkKx6I&h(0-&O_f7hf6KcC8wGIZp8>`e&u(CIk+4U{^dhPCx<86O!#5{8(BcX;$^FY1Q;KyGW@&1v`u5?J zAB5fI)jD6I(nLRLVf^}QNJCkt=N6B&79W%j?qfp{lhCCxH(_tNA)9hUBBV=uKvX~; zC{Cm4*ya6>;i_+BMITlEHq*&!Uj0kSX&OEAoZS=e23f`;r*tUv8yuM@;C2S$SKdhKo@08b<(kEed09rrzIx9A4m5OB(G_IHMS(CiF^3AVuaA=dI%}xD0V>60Vh=-|QSh z<%uP;m0mJ;?ht@>!`=2vSUEzlw%UsQaVFlavfJ7orGC8ArgkK=?udeLaK5u*(5(B< z!}CPJeARwbZ?cA`UH*hRP#(vXn*_W5%3%QUI2 z{@J&qZO+|1~rQCZ=uqH(8Zie6GqE{s%S!jrZ$vixhR zI2rgV+PRtz@v728zDcym1{wC5y=RJz+O7!r_hPRKZ2hpO)`ZvXR>Bl}bYqg$D|?EE zN#aOm<})^#PNUMRkrOPFbvLkCBiD!1^j0Dd#(g5!s6IbK5v8@$L;qkHv>XL~aXWtj? zb)4KW?p(#v^?ffi5s#x=P={qhdn#JF-`MQ(jb*=(m__0#!Kj~At?!yd_t>c!U3Jy! z4029EDZ}~+yd)uWf zT$9}}Z>yuh_Bp+xJhotR8*4w4ld5pC!EdxK8nw}}U)`OJR!w;2ZI*m%wfFH0@7ls+ z(r1Jrvm>=}(T7vPN~cU+{{1OOuG<71(MP*)VHE0%S~0iI=J-Vk?YfKZ*uf2aG1zi( z=13`Ot3zSu^_4o(&);OZ?_O{wu1&l~%U>)GmYYHjDsx|yZ|p4J+i*K-&l8ywX){Le zkJ4j}q|bzBt#zwh`*k4P07(RVwANeq%A7*iyjN_F|A=mT_uGWZA&xr~kj*!_o>5`b zpSCQsL#@aap_*LlxVgU7$jJFhPImLsOKEN!YrcwzxRnGS+KvDdEg~`O3kQg`DK#F2 z%DXi~`b7m){T$Z|Pro**mYn-yATd|Rri>sGK<_0fS4`Y9a=R(ihmPmP|L2407-L@%vRrz*YK$7IgLxI$js zI|rBET){?<>4%+_Pk+tx=m{xFuxJuAj+EaM*Od`+R`EjF$E2sL%93c7&z5-OfNJ@L z+>LWee)o;UX34X+L)7{Xd2J(+L)0$q`nc51Mz&R3ZG1mRu-7r9IXCmR_F0>b6$czd zvZKSDOp)M-stVk!T~B{w0gjuYHJc+>1U~<4L4r z^B43%W-L#1)>k3e9K$wFT|JVn>z@Di#6Gzj7=PpGx~SkDsM5fQ1a&()ub;GZ?e6-~ z3^Jg6AWY}fLv61YNdl3&bh_uJEr^Qz!QaTxDndG$`J^83Z&@HEytWhQDMABJFaZP>n zK+M&ysx1c=k7DQAFl`{K4v#JnInJa%8^S7NYX2sfUBfCh_%#qZdjy?-5hR5L&sP<0 z#XNM1P|Mg8l5X+5smOK5EsWHYSn?NbrSJ9^S9+!;9}W07S&1Ch@{R#*q0YmuoibK0cG5R67-mx{fX_TRB?Cb(53CdD5vhX$hs2 z?!AKq zhdVLrvwWNhNA}Bv(2`1PhW*BIClgyP=eqfY{rcG?xRfRn9kKF)X%=NRaKBY>eM4kI zhh8ua27bq{Ro&x)_45AZ!eXTQ<@~m2*k;>0NSv?%(HNh}nNctd5cO< zCMi)F#gllqqB|K{cZ>Xn4505q0+Eu+8$ZYjyQxXHMQrhhUfByAUMmSWXQ*HK%J@j} zJ-DE*cMv;sChcge(&ak5_H4qloc1+nfhxD8%v$2=Y_#RkwuBw)q2M~0T18J<9Q50C zUNcgT+aGe;t!S-Du3W9C0RAI1#L;hlwM}Z#6n<>M`z-)RtB7OjU~R6hz%WTZKmnR8 z$Muz6_3Xzdv$wvUqmte^e+pa-RDF{tS2jY@lia8KYj{akE`|1E8d4V)Se}}kQK#S>kv6FGc zM%>m=^&yaX_dNQgDhPReXMylstL!o({br}I(l8-boDg^&IIK?Ux<(qtXGw+O*AU`X zCG}pV^ft9r1a3YdE!|tc)0Vz>d#Mt~Wy#e=&WJAbN;jae;Wb_cGP=_Wc785jus)=x z+lZ{43%Os2O8ehi*)V+s>wMZv%%oqD+FfEZCQ8FdJ9q57;o#dA1U)tsh?GO#d1tY& zS71u+U@n3zwdeb>eHv6v3dhT+%!)dX=!nG~V#z6kg#>{~6z->sVi=*~v(G5(TIN^Hp3*mZq zaRH+bzpOnrMDFBf9zsHhBtaiPZ6C@(&Oi^{!dht30PN2vtsYm1KL(rDO^t*7@H=Nc z>j75mr*CM-T{J>qSbO4X^Ih`nkE|{E8;7;O*>2mc>IZKhmNNJq<@WY+13Y-p$m0ks z$BHnKM$QoYdCnn@8^Q!4qp@OV9_d#Lbhz$^+HNl@*~s18TgjFx6q5B<=Z0z$T%Ip~ zzloe@#@Z4{@2n+IDmI+)0P|#f48qCq_?8mT7IU-dW2lq0s=wyH<@)Bw{Fd3pb~3EY zw@6-ehUJymMs`4J)+pw>ODR&bpJKS7$9v88{khLud=*mizn9XQ>HN+T)3>fX;nJb=LYLrH zAq+#4dopG&Yr)$O-?)N;B@+zDNv(q25_nyaSB>PjCTP7`WCE~o%=n{w4@dQ-6z^Q5 zVwOH*6m>1enX&5Lm68_nm+fSbBvtPI7nQ7HdPIAwUFyPW2Kx5>+|>=H-$Wro=^98&_4Y`4Q)aGJk6G=5j$cHt_*)MD7}6yI z){~#EfvV`)!Q|!>(4_-sth+Wv(#K}*y=*1?oNpf_t;Tq96M#s5;2g&&8=O7G0yoGY z@9sJ-s)0m;Xe$mO#EYi>(B9Q$O_{TLFGzZ#A%pmYW)R}$SEKf@H6@XLsvaLZCm88? zsLNmO)xUyFt=7vQhPhNNhM~iJBMr!cDoF4$XD;{G3?x}=Q;O=eWsEJlQ2a9h#POTu zMM{RK)#Yx>IcEwAQeSStYS*d7pA6eFq;MI%yx+6{GQu1D+O!Lzv*)#U3=#=HQsJGX zr~XDe3CRXgqi@P;L6((OSpJrHo{4Rmu&H@GcXh^d(j=P`bpPXaK1o4Y5k5KfS!m zvGm@QHIrkF##?~)?!lcZF8g=7=xOPsYh!92&#+_0a>k34FY%7#-9t-W=cvEg1AQ`!G&rLG{vE(=|p& z6{)$4N*%bywtwdcWO4ZBwq+Y6G#)+9eO_&M7qjAb6wt(bkv>-L)>A}z>b7i1<`m=C zrap`LB>RqbNm)jQg@qYJG^sBkBKRif7pjqyg+Cb>w&O|Of_=@%(;AN>H;#Se7H$=r zz3|~*fwJ=gQ?5@%py;U!xjoiCq{Lsf7(Kl;OZnF-zFTW&6>f_3T4ldXy2;Hv#qb8~ zc;2rqqw%}3gm&G5hA9pK2N~%Iu;k3e`&zHr(|`8 zNCdmGN#(&-1$Wo&XGhf!xmqgj3{s<3JOna}J2@i+yk z86lIog!bjWL7x4$am@J}=nom*yV1$Rj11vf#|IzG$OcC>)f+^O+35L`JML&R)4LyZ z9i!6CV4utBj@e)PzJF*9dTu5N-Ka47|!oaXCD6M2~xLZp*+6 z$25UYee(7)+>R!fIJY9vp)NgCWgVnk=sd5aer2tDl_ODjX`I`S3sA zdXjhk=JF(3r?Q1Pv)V{gdlfXpJ6&Qg(0$y_9!Q7oH+|RxC*? zl*9H#nrCrnRp?QHms|W?*w_R*rQP8zYRoN0?4C;oy@w;Rc%E~9sUD4r*|XZec?Dh7 zl|L67`w7Sv1LaQ^zEzK+1`f@wcZMCVVFG5u7TIhaDZOpHh#p8wo>1m9<#wg;h~Pmy zbjI5FE%j!~_bbC>kz^>9&_Sj8P@UpkxJSM;@{~%b@a`dY@mG>V~XGQ7vtEIgdTH}DcSJf5AJ9RK+0@ug(7jo%ey5$RBbAdTA2 zwxbl4Tl+HN$wyyk;!-v0nkvx<9j5-K`BDK$F@26;t&vAi6uL#UD{0Su&|3NObYC3iU-UQ8%Zr zwm_Agej5C%7HF~_zKi-6SWM115lBVo`5!r)B2gE|d|`~eL*#Z9|MI81#qC&1=ae5m zKYU(|c~9Eqt|IQP^<$2Hz!3^Qg)^D^Q(YOc#F^W*qh{0SMN=&hpmjm;&KN87eNxZ1 z->zoVhEm@CMlvne41ID!n{Q#w@Cxk7ABYOHYl0n6;OuddTr&kH(#GL*4ps!oJ5g0j z|MxCz|4V7pFZ}ev5#;XXbyueiFMcFUX^v72^cH`ks!3B7PUJezSlBy_&{_M`AE}J)UanZ z`ngEqK}*=&eF{yyiQ22&0v?#~4`898*4mxgh@B2wzh@0h)UE&<_B)T#?)dRSSx*N9 z?c`Y-68cmyiGja)?sd*3>zurCXxlwP>#ZY|YN(Cr)`#EuTYLr(?=ddco_k}NG4q?? zq@(fHMC4z~v{<=;P)Dx7 z`IOe^#Kah<-L7%nwGvy-Q-6)Jfp>@!HN%3)X4qAS-j+o!51{4V@|F!38G*~Z?su<3 zlbYkAoxqW^&yZ{sM|+i^0jc_|wbF^62O%>L0kcRqlfCys*c&MI)-#BfF*#zz*!x?|7nbExNC zod_>;sYLM_)<`kKadZ}=uB6rE4f^y= zd1;N|uA?s&EAGFHYwEb_$tPNlP&f4ucBsH?s=Jp-TpJ@s!Kfmh{P6s-s_h&O*_H@@Fo`KGuN93Geu)6)+mo5KE9|PyhSY`bMvP(Y8qoDnpFL(eE<6#9RFl(KX;c7P~)xVD^zCp@P5R6JFBjZGiXR;*mbA#J=s9_FzU#TQc=!Km0m3rZeko3SIQc-Gi3KNcN~u5P2z`rT zyPhxitVt}r!tKw7b>Ck8mFN$TP!Cn`LPtv@maq)z?-0zV!@qR zsV1rIx{wVS`SS9FX?9)H)b*$jSCM3H zdB$%Oi7yC1bv~7Y)E(Qf_o)7Sg66UzD=tDB`RdEl-qaX4T82A9!qnT+3d$q!|KdLk z5u_8(D*3S!_bufV4k%7vEKxA&blAQB+0F4h4ko$9Q!0>Sn762NkeqRR3BO!NsF~op zCdKdd-ruulsVI%-KTO{C_S)Lvk+Y@$(lh&sRQS@RI`oM*Ub;XtGb3C1)%2;vZ541> z&0%X47$N?O$0+w*;|3p-mx~~3#54O&dD8|#Za-#A+h)kSU|)0D3Jnrt*UYG$InP`^ z-xk`6K4zPAzl(MmCT}s}y490Y==j1J`eXz4?kr9$>Le?S$E`lZ+e7ceGIKtU9#JZr zlpnq7sR-ZX*y@zRUAs|3{YQv&-~d4mw;J_DbOth3K8E~cnGD4ConPIqS3GigOKG4p5LPLXG-g^{RACXt1;h-V^^XiYZpTwfLt(1 zlK0dP@idwgqu}$$+_tq`h`VuO8Mu%soaUVMGY;X&+(ON1 z9qRG>>fFo@g3C%!3ZD!ieuCcW?3?*wuAsAwBdx38SeTOW!m%lw}>@~mt_+% zh4p%5fIvTvDsHS{;uQ->@t9`|#EY8^UviC(Hg}ZMW6&?}m~kLKEGZ4`nnKR}K+pF& z6EkM!eHI>4PVHH?9wvK=a_&qo=zbnV_B#3hAiqZf&Sg|Z#RmRvLz~4yWj-;?WnC&5 zQ6`FesQ!e3&er#AiFx`pPwYC<%eNEVtMgdqTXD~({HX_A>;_qg`% ze)xbs5}~P>ck-*Nrc$?=@^)@0Yml{#L;x;`@#0n6c}Cbh+`eJ_0o?SXj|Q%q|yzg0-g8_CL?Fs!i4-elq2U zZ`av7uYKLlGs{K`yt6p??Wwaqw|?yU+-l(eEbqkXIDGdNj6yR4f|X-=ed=B2PAfU1 zw^>W5$0a36$*0}n<7uN^GYvlSrC8kq&+rM`M>_656X}*kK#o!akoRcP@v?U%)qC+zLK|g$B-l$Wrn`#EVr`CH37QUjUGEZ$OP<1o{gR@6y5dZ*Y7a9$nYKh& zBU)%wE7_=x+?iY;l`hf`_eP}wZVgdd57*?lTBtj{HSu#TFW1{Sahs<9xdu#Rpook( zp)?mSjZ2#@^+dfqOJ5{NshpG96fu!N;687InJuL-!f7eH_;DT&W6#S9*SGFaII{<2 zfXUWZVzDE){K8LPi46iL=RQw)mE1$2yy;V1kdl{OxY=om`|S72?6mtLZ}5_~)x%gK z>)u-2o|DAZ9hOhG_iWu9g3Q=gFKozI`d0k7TTQ)*tz&ni*-F5FlVosQcxystT5(Y> ze%DZYJXW5)f!G)S*b?OSzj+zpK#Q3Z1#1`?T+3gXY@}SKNPFNsuY>z3O#7wcm=vZhc`=RH)BciuevWfY|Ljqc+MW57)fiMwY(rJbMi@1k;O^wza7njx!OOk z{+OqFo4Jg%RUDm{7{(Yr@h7BH80;0QdqjgDsj%A4M_~%-UVg7GPbFQ2ALMKNvLY)u zmM_BBc}DSznBBulrpbhDKUt&5gRq;R#)QkpZR3Uv-IhBwdcTW~smw@kxO;RvvTc~? zR^)hIDG8n0SAo>th_Fs#_OT)=o$>kL3P1SB{G)IAn_49f;2!Qv%g#7=2$_!0D|}br zdss5Rnfy3#`Oa{nSSrDiMX!t^@?sJx_%3OX0lk3MfPUPHY+pOz-_&9<{3$xP7wHc^&gWc-dkV|8 z=3l}>mu~oUs1wpe2LGNxVc_#BORt zJIYWk9a_w$ST}IPuv>;zub#oX$n@#DoYBntZ1Z89p6{x0fFhlGpSkvRGZw4BS(2Tq zwHm=E8&0)E_=i^KcHJ4%Bn71`QFKf&=QnTcxi96~~qUTWv&s%;V z=3c`jN9O(K%K;$+AqT;cjoGXO3se+cIGEJ3`?c-Mp6H)mE3O0Rt)p8A?qDymKRNA< z9QwtdMXjvXj^I6r3tY~Lq++v;GGmNXmz*Yj#&*CMdXHVtGdT3aoo#!G^kRBvHK&+L z2)Iii`okX#-EMqCwKOAgQXN+mT?bMBRG99Ji2fR*Z0s^rDqk%1;?an9t9h4U)fldG z#Ld%N3cjcHRc${rc|gebaVus&(dQgDv<6G>lAjjrNt&ZX-OM4)_36|&3PDnwVyXh) zYWVHTt32Ig5J4+hS~%QiQ_L*AI>G3ficVUrs9XabGyY<%wW#reqV0sLe(b6#ZO&df z{J6SsRQ)M!_lpaDIqI%Cvnw@kdDcW8qjx;PnfGeCq1|Bq45d&#AtcIZtFLFwD%10= z^isz)eX)KXH6<;VYUMZ$`-M#85N8U@l@`|L%M08SKdQwW;70u!hCdwC}c@$opBQ?uT;RNTw$^8BZ3ig`y%)1alVN_#)M& z2A>ui+By0fH$R7-ORI3*rW<9Xh4b5hk8Bp*;hu6TU>lq5v&E*D;9E5qimSBrNu1CY zyqEM$d&*VvX+Vsj>v+@lQ8oRYGS%g)5 z>yF%~ErYhn{&sFW{}ALDHZI&C{}JmT!dJO4-at<=HE0?stY1!!i`(v7Xj|U>zR)?N z?R|TK^O*U>fm5d2L2a2&`cFCfrVrr8p`@MHPh`R`EUYw&ez+2-}+bfZ*8%=yRN5yd*;>a1c;-cGqZ*5O( ztjL~|@3CS~CAcRi5UwsRp1b zD*mWO1bTWltcmJ8azC2H{U$2VK-6i_j;ei6T&Z>+%{~P^wqMVx`qtg{W#OJda%*{q zqBj4$034?|z6<||{kdKj?7hCQzU~#9P64sE(#}7-w7GKx{-`yr8iSu29KXD!d5vv= zi}QQ#IX~Px^%J2ri9f-n+z>#)NPb^N?|W+}?-4$##(dqMW50u(JZHb2qMLTA?H9MBwb5XHs>!f8uO7_^1 z^dWb7R;<7(RHLvuSM&4xBL{B7`GZCB+-260&k=b|3X1aDAT7X-Jn`Ep(CIDz$;U`rdgs~n|+Zs%uT7fz!>N-&k7E>$jFR7ES)F@2sZ==%WI{E za!NX91}7|E->xcJ4s&?XShXY5gz7}957-U z#I7sOG&p+i4T8fYTMJy;+e+pz;!49)k9nS;VjGA-{}}o zg&KKo-G95G&##j_8-02QWkGN4M+5YrGBYm*hi%Q6#erc=Qr|dzr~w{rY2(+FTHOP= ztky@DG5dE@Jzor9KA=E!sz4vE0OhCMx?msB zLmq1QgAOD#wLr2D!`6eD(r9`Gce!)y0UuA_TaxdZu^FwPA7YSAk_n$1bW4bfpw)O9 z?~Jf7^1(&UF*?Ta*XOe;!LUetTy+4;A}qM542B>hZrIF1@(S}Cz`)9x8#cAjn2G`2 zn2X(x$%OpC<#qpj_=$Zow}dzT8S^*Mgl(8D{*ip|cC5fTv1)#@9Br2Z2TSC__u#VDaI& znZJwwvHgUh^;cMu+lds+zIA!zo{R05c}L+Y>PDfiC~O20+r4&&gNV zc{&)=SILg~)B*VS>fs_iw;7vEi;#fv7<lOR6*CRp&vpFi!) zEaFH9XfW#-f6#a~^|={q{|Aj%PE3Fy=`*vPuho}yX@3^}lJbSm4BPf*E52lE_5mQf zber>n{_^9}#u2hZGNI&u+EA<2N>~Q+`21HM*|9JcEbZ|Zk4Pv2%_p!G*HI)czVpz;dA znViF5Ae2(k9}39%qa8*O!#>5$*mM73a^>@9K$&N(_EtV7pHgroz2n-np*S$hC}Oey z;(rQye+L4X;}vR;k$KJrf8A-EmFrvGvYtzL)$pj1@uC*>cSt3JrLRpK7MYH zUjx8!Ql`FD{`FdWPyZqN-2XKjDGE6lEZ56X;cI0}3_J=D`=6R@nF2|?;~&TM(hrRb zWLX4-8~>G0=fR33E%F1S+$GFw!JKH!9|C$a0kNK6wPpF@Y0J&m8RUB$5x%nd zy|4JC1^?tLo}@h&@P|~Nk5k#R4B8&;EM4FNrdDdA0qI7IBV>02d7W(DpV1MPo%_14!F)&kO8ykC(0t1leN*!9tNMLXm}^ z2^~#>Z>6etfew%7*|)Kd2`N^btZ;kKjx&I@#l>6DAT^|-n65N;1i+smRy6p?iVI%z z@_#x)+|QSHU>ZD{!g+fLYt$19NR7PGK(?5tr!M%^v0|0k0FJXhsIhe9-2bfSd6DZ$ zlK^~6U?$t4_CJK*N)i67Y|cH`GqaKv7o=^$^X1EGKo7O`495HYdBtKBHbT!^mS2^H zILe^)m=X>-{%b35SuGnEaMeqZP7A1d& z12n+{`zK;b1-l=yQV9PCfN#rZ>i!;2(1!upU!~D+67@Z34p>e)ner3oY*n>qzl=>-r`FCdkFoz2M=w-z^q`H#ZDf8DLmrULO z13ZEip5@EdaNg%FaM^7VK$ej=>S6kSs;3yw$H^zznP+-o8erX)wMfosCfEEIJ7ybT zJkVyHzroX}`5?e*)gS90s6^Ai?rj6oc9hQ>Bfo)e}h22c$ z+il|?zc3Js4g$19UBtmae+?uo;IGdf`t%2Wr*-{*4_=I}yVm zR$tbCe!<{%6Tpg})OP4{?>M15;iY8|7V-8Fce@wnJl!ro^Yzq2w>n56A(+@E-h@^wfOmV zo4u7P=rh{c3gcTM0-gUbk{3fr9>G6bz^nYV(TydG*6u~cJ|}XXI;Ucq!TTua{!YZb z6LqYpCO)qL%{DwUtFVWLf8ucU50-OjaJGMS;u<(9P@FGbs|KgbDL;5n$@2jdk>5mXv3ZjT-WK1w04csFryOJ>`r{Yb~qN07v&K&ReJM ziPV|Szma8#7=tMr?=wlWKnLa?{Fy&OIG0RNcVs_*&krN7>?zosW^CFZ^4Axh<9Y?K za{B%=%b!5!*{)fb3+KvGIz^H8ZOh`$qAwThAfN@D;s?ox@5Mv1A7fq_W*Qy0(^iEF@YXNEXH zd$X09vM2Zs%ZM<7l@l)8oIcCsQ~3(BpYlOb_^m*r(htEgl_%ha$9mKc5Hy(%t~#oZ zPgW}{zg!_Vu;dAfVEFxEc5^=gRAp%2`u-;cbZLO!-LOA3XD>r*r5eCDRru-Sq&e4b zCv@ROt+Gc~`@?*=nZ*Z7;YYE__~md|4jjY^c!2Xti&cNJzJW@_Zb-a^<9H;f0fT=m zvJ24zP=IAN8%aw$zb05bAW)|61AI1x^W{oA0B*MNuji6Qp-LTAQ>W4&&*O~R4D>3$ z`n(U@`3~2`qVC|cr0rdD9D|ZB|A-Kv#LNX|M)A04gkK|Ktg$^hUkK&&Czotb>^at z$l&HWmDNCAk%3O=4`C=sHhoc>_RTS?+Go!)0o>wcwD6PTwhvVJfehDiluh4$m_pyg zax!)Md}pq288O(*pM2#mDyEppxD63m^v=+dg=W*A)cG;2Pqk-PB zL+rp?OB|7ffn|UOEHe3KyK;+1w;jPL=zAAnf6imj5Zlq>_2_N~G|H6Qfob4tT}wH5 zO-ffJ;foej!u**}PmB$iF$^k+0m zGk}nhJGDv2<~rXu{(kG?eKqz9yiU8W0JpLc}F0Tu&L0i6&pf@aik?m2A4V7 zV;qqBM^_-PUl8*~mrSORajkqpK9dqZXJN$DwUGlvTQIKymN^Z>S-aF+U5^GF<~1)Q;PLT(5cobV;t}8lWj| zr8<4ii=vb>N8C|UkKZ@X_>E?UpoTjkW={Ax7%=B!x9pV#@93LC92=MIwHCa7u)Ox~ z#;!09KYRi1XusJ5l@x~$c48GXSHst9yb5xdVZZK`u8{rsMHu{>>&+&BJ60E%_#`d4 z8z^`I!Mm{qJl|!M7PewQ*|r~=bK>G1J_oH%GReF9lDGyfcpvMF$_ZXdxOg7oZ-jbxzp#Np z?|y?;m;Ph@rjGoaX}=1ReJZf=qomO;@v;k71#vGkMIjG%a4!T2Rq+2`07z&(&u~7u zgnZnTTtd@Sga@DVF?JU)x*4X{ry<}EYUBkQT=@^svNnbSYrQiGXE5_-XeCu$Eb@m& z@3Z7I?-E*PolnD2GULd0P55{wRGTljYfa_mp}JMVOSF5@soWz62;(080~jx*A3jjfRS{v$ zqzhj5p)AvmA91j+BPTJFMWE2twfUl-;-Xs9B5Oq-X-)&G8*@jR;tc*j)jvTWm}0$SwgMul_%PcUKN7Ey5Bv}QTPYz zS~n#K`98k;aN-uIi#rJaTn;m?{as#6(C`ynJ9Ui7k^OuI7{ADgxY*LhkRjX)CV29? zT9^~c=H>$TsXs42nhS2Bb~PFxKgEMia7{2&Z)3G_KTeuBOul{oyx7no(ZUyzXN=CA zmQU@JMjvy`mjs}AZK0uZoc4fE8hUD0W69(gL9&bsqUeENN)J==UW!C_3f~pH4Q{R4 z5j_~3{|6v1?n>~y!L=p(@gyaplD91eo;);p5!$^<@OR{=)FMO`!ZNGTJ-DQ@ogg@%V)~c+=w4RtXV7mEo6BZ%vnEaA3h8)J6KSMR+SX z0=*;0GYKd;d9TsLEX+>n>pYP86-fHltb0O3{Sl>+6pU@6h5AwXb<5eiae@M1t}M5E zblcgr#p3y#QfV|^C~E)JgzrL-^!gK~Gixu-B{B!K_J4b=ov|~_{l;Pi1+`mKapFR=-Kn8hWqup2KX>enpv6VAG>t> F{{Z((MkN3M literal 0 HcmV?d00001 diff --git a/android_app/app/src/main/res/drawable/rect_normal.xml b/android_app/app/src/main/res/drawable/rect_normal.xml new file mode 100644 index 00000000..08cb20d6 --- /dev/null +++ b/android_app/app/src/main/res/drawable/rect_normal.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/android_app/app/src/main/res/drawable/rect_pressed.xml b/android_app/app/src/main/res/drawable/rect_pressed.xml new file mode 100644 index 00000000..2cc15774 --- /dev/null +++ b/android_app/app/src/main/res/drawable/rect_pressed.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/android_app/app/src/main/res/layout/activity_main.xml b/android_app/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..e12ea797 --- /dev/null +++ b/android_app/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,6 @@ + diff --git a/android_app/app/src/main/res/layout/activity_newentry.xml b/android_app/app/src/main/res/layout/activity_newentry.xml new file mode 100644 index 00000000..63d45582 --- /dev/null +++ b/android_app/app/src/main/res/layout/activity_newentry.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +