From 50d78010f99f132dd1f5b62a420ef30e2807b974 Mon Sep 17 00:00:00 2001 From: Saran Narayan Date: Sat, 8 May 2021 18:30:29 +0530 Subject: [PATCH] VCS init --- .gitignore | 15 ++ .idea/.gitignore | 3 + .idea/.name | 1 + .idea/codeStyles/Project.xml | 123 ++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/compiler.xml | 6 + .idea/dictionaries/Saran.xml | 7 + .idea/discord.xml | 6 + .idea/gradle.xml | 22 ++ .idea/jarRepositories.xml | 30 +++ .idea/misc.xml | 9 + .idea/runConfigurations.xml | 10 + app/.gitignore | 1 + app/build.gradle | 46 ++++ app/proguard-rules.pro | 21 ++ .../myapplication/ExampleInstrumentedTest.kt | 24 ++ app/src/main/AndroidManifest.xml | 50 ++++ app/src/main/assets/new_models/$ARRIVE$.png | Bin 0 -> 2480 bytes .../main/assets/new_models/$ARRIVE_LEFT$.png | Bin 0 -> 3773 bytes .../main/assets/new_models/$ARRIVE_RIGHT$.png | Bin 0 -> 2537 bytes .../assets/new_models/$CONTINUE_LEFT$.png | Bin 0 -> 1275 bytes .../assets/new_models/$CONTINUE_RETURN$.png | Bin 0 -> 1826 bytes .../assets/new_models/$CONTINUE_RIGHT$.png | Bin 0 -> 1294 bytes .../new_models/$CONTINUE_SLIGHT_LEFT$.png | Bin 0 -> 2147 bytes .../new_models/$CONTINUE_SLIGHT_RIGHT$.png | Bin 0 -> 1269 bytes .../assets/new_models/$CONTINUE_STRAIGHT$.png | Bin 0 -> 1002 bytes app/src/main/assets/new_models/$DEPART$.png | Bin 0 -> 972 bytes app/src/main/assets/new_models/$FORK$.png | Bin 0 -> 2925 bytes app/src/main/assets/new_models/$POINTER$.png | Bin 0 -> 4431 bytes .../assets/new_models/$ROTATORY_EXIT$.png | Bin 0 -> 1946 bytes .../new_models/$ROTATORY_EXIT_INVERTED$.png | Bin 0 -> 2616 bytes .../assets/new_models/$ROTATORY_LEFT$.png | Bin 0 -> 2126 bytes .../new_models/$ROTATORY_LEFT_INVERTED$.png | Bin 0 -> 3066 bytes .../assets/new_models/$ROTATORY_RIGHT$.png | Bin 0 -> 2281 bytes .../new_models/$ROTATORY_RIGHT_INVERTED$.png | Bin 0 -> 2869 bytes .../new_models/$ROTATORY_SHARP_LEFT$.png | Bin 0 -> 1878 bytes .../$ROTATORY_SHARP_LEFT_INVERTED$.png | Bin 0 -> 2826 bytes .../new_models/$ROTATORY_SHARP_RIGHT$.png | Bin 0 -> 1897 bytes .../$ROTATORY_SHARP_RIGHT_INVERTED$.png | Bin 0 -> 2612 bytes .../new_models/$ROTATORY_SLIGHT_LEFT$.png | Bin 0 -> 2051 bytes .../$ROTATORY_SLIGHT_LEFT_INVERTED$.png | Bin 0 -> 2688 bytes .../new_models/$ROTATORY_SLIGHT_RIGHT$.png | Bin 0 -> 2035 bytes .../$ROTATORY_SLIGHT_RIGHT_INVERTED$.png | Bin 0 -> 2693 bytes .../assets/new_models/$ROTATORY_STRAIGHT$.png | Bin 0 -> 2158 bytes .../$ROTATORY_STRAIGHT_INVERTED$.png | Bin 0 -> 2866 bytes .../assets/new_models/$ROTATORY_TOTAL$.png | Bin 0 -> 2096 bytes .../new_models/$ROTATORY_TOTAL_INVERTED$.png | Bin 0 -> 2855 bytes .../main/assets/new_models/$SHARP_LEFT$.png | Bin 0 -> 1240 bytes .../main/assets/new_models/$SHARP_RIGHT$.png | Bin 0 -> 1870 bytes .../main/assets/new_models/$SLIGHT_LEFT$.png | Bin 0 -> 1606 bytes .../main/assets/new_models/$SLIGHT_RIGHT$.png | Bin 0 -> 2326 bytes .../sharan/experiments/myapplication/App.kt | 27 +++ .../experiments/myapplication/MainActivity.kt | 101 ++++++++ .../experiments/myapplication/TVSHandler.kt | 225 ++++++++++++++++++ .../services/GoogleNavigationListener.kt | 20 ++ .../services/MainNotificationService.kt | 220 +++++++++++++++++ .../myapplication/utils/BluetoothHandler.kt | 137 +++++++++++ .../myapplication/utils/Direction.kt | 35 +++ .../utils/DirectionImageMapper.kt | 98 ++++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 +++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++ app/src/main/res/layout/activity_main.xml | 57 +++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3593 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5339 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2636 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3388 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4926 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7472 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7909 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 11873 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10652 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 16570 bytes app/src/main/res/values-night/themes.xml | 16 ++ app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/strings.xml | 9 + app/src/main/res/values/themes.xml | 16 ++ .../myapplication/ExampleUnitTest.kt | 17 ++ build.gradle | 28 +++ gradle.properties | 21 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++++++++++ gradlew.bat | 84 +++++++ settings.gradle | 2 + 86 files changed, 1890 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/dictionaries/Saran.xml create mode 100644 .idea/discord.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/sharan/experiments/myapplication/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/assets/new_models/$ARRIVE$.png create mode 100644 app/src/main/assets/new_models/$ARRIVE_LEFT$.png create mode 100644 app/src/main/assets/new_models/$ARRIVE_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_LEFT$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_RETURN$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_SLIGHT_LEFT$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_SLIGHT_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$CONTINUE_STRAIGHT$.png create mode 100644 app/src/main/assets/new_models/$DEPART$.png create mode 100644 app/src/main/assets/new_models/$FORK$.png create mode 100644 app/src/main/assets/new_models/$POINTER$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_EXIT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_EXIT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_LEFT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_LEFT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_RIGHT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SLIGHT_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_SLIGHT_RIGHT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_STRAIGHT$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_STRAIGHT_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_TOTAL$.png create mode 100644 app/src/main/assets/new_models/$ROTATORY_TOTAL_INVERTED$.png create mode 100644 app/src/main/assets/new_models/$SHARP_LEFT$.png create mode 100644 app/src/main/assets/new_models/$SHARP_RIGHT$.png create mode 100644 app/src/main/assets/new_models/$SLIGHT_LEFT$.png create mode 100644 app/src/main/assets/new_models/$SLIGHT_RIGHT$.png create mode 100644 app/src/main/java/sharan/experiments/myapplication/App.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/MainActivity.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/TVSHandler.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/services/GoogleNavigationListener.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/services/MainNotificationService.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/utils/BluetoothHandler.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/utils/Direction.kt create mode 100644 app/src/main/java/sharan/experiments/myapplication/utils/DirectionImageMapper.kt create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values-night/themes.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/test/java/sharan/experiments/myapplication/ExampleUnitTest.kt create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..643d213 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..eaf91e2 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..b3405b3 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +My Application \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..b5814f1 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,123 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..307554b --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..7d7ec2e --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/Saran.xml b/.idea/dictionaries/Saran.xml new file mode 100644 index 0000000..f0731da --- /dev/null +++ b/.idea/dictionaries/Saran.xml @@ -0,0 +1,7 @@ + + + + navdata + + + \ No newline at end of file diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..05e373b --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..cb41453 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..f1b63f4 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..59135fb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..93e4b17 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..1a72bbe --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.3" + + defaultConfig { + applicationId "sharan.experiments.myapplication" + minSdkVersion 28 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + implementation ('com.github.3v1n0.GMapsParser:navparser:0.2.1') { changing = true } + implementation 'androidx.core:core-ktx:1.3.2' + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' + implementation 'com.github.weliem:blessed-android:2.0.1' +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..64b4a05 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/sharan/experiments/myapplication/ExampleInstrumentedTest.kt b/app/src/androidTest/java/sharan/experiments/myapplication/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..f318271 --- /dev/null +++ b/app/src/androidTest/java/sharan/experiments/myapplication/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package sharan.experiments.myapplication + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("sharan.experiments.myapplication", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ac27f5b --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/assets/new_models/$ARRIVE$.png b/app/src/main/assets/new_models/$ARRIVE$.png new file mode 100644 index 0000000000000000000000000000000000000000..06fd05d059548368781a77f5ebb08d255ef109ad GIT binary patch literal 2480 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$CONTINUE_LEFT$.png b/app/src/main/assets/new_models/$CONTINUE_LEFT$.png new file mode 100644 index 0000000000000000000000000000000000000000..efd28eb12a3cc5a70a559044ce5882772956bdd9 GIT binary patch literal 1275 zcmb7EYgCd40R2Q$W@3^OrfZc}sGH_mR%&)Y0bltDP*emlL2|UsA|frHJv6m2N3Bq7 zs|+mDMGA_NEYGG*qcY^nQe(D3eNwI|nwE3)XJ>zR&$;)Wd+x9M=blWAk3=|nI068G zh>pUOte*9OaC@r?LvNq8njJ4ZngX}t2%J@Jjq+$bj&i8()ksD;itXO}X0p?dz(%6H z^n^3wb9qP{9Zo>w+%lK&Jxh~`C0kb_b%gbq$8qdN-0}nDb<6Q?>?i@D2S-WE z3=XCV77l*Sxwi$BT;OR3%)$2^X7+2}b(sXl3&ET*!P;Xk;qZTD8$pdPh+POTAgkM7 zi|1=Xs0%+WK4}afkw+~Sge8q%8xj&w^(~}?;`rcWv@Q=4a^U0B*csVY9i5v%HYrQ{ zvRXnqUyBddnQ0KkE8dmn_3V)bSyZE%e1k+Z_`^ZQp24k(`!q76$mSv-ydtvi zza3SNDVPPQF1WgT9hy-M2TD4ZK6MsTWhxoM(xl9bDZmk@5t7l+1y-%pI5H8rg%?WZ z`=Sk=%$%5)*fX{~|EMTm3Ba(`pRx1?-n20g4bg26pxTk^5u_Mcf~)_hEhvrL%Rw|} zKNjEbVLxW8K(A8nK54$R-Lu`k9p!T?q;PdECnhJ-6yw=zmQI-llHa4+BIvrdaTQjb zNN;#eEn7Ok$J1%8^s~OX*n;%1lugx7RcTDLjHjaxWi2tPV%74B@obs!T9F9O66QyO zmF7VH)nV`AF5-~Gb-%Bh*r>VIs<~m`c5`=-X_@3uY|o*LB)tVm=<_;`KPaCG{aJCkF?Qe? zf+4%CVa=UuOHhNp@(z-^&#Vm;-r%E#t!pW(&xe;Bspl~=z*JVKKR1z1qP5yu z)wP9tTiB}-CtLWiV3{XR%lT%sP4QGdBLl&(vRf}%?(}Dm!1=j?us=5qN4)nk0!l%b z?8G(JQTBvsmQ$R>nh^fw0ca3D+djF93^NJl;cQn+K z1*h_+@$R{hQ)>3i`pN2HLFFHOFbR+8k(ptI8*X$q#X(ZdXH1`l)^4pBqHx`_(rl)` zf@k@uYaKc0%*|2997NO?k?kVT>~>13=_|E+c0Vm~|}e@M0{u QTHg$aCdA{L!yvr2UF!irKG5!7A;0o zf`AtPMD#_8Mk8Y4gJP5i|aPHFC zrtCfE&di;;yXW(^*>h*U_k3r*bI$Laxlkw+3WY+UP$(1%g+ifFD0D;UT0m2%tAVw^ zali)POyJFfzX1*d`+z5aM}hl+1Hf~@fe^y;fhAO>Px!*-n~OTRlQpMSBoYb&5ZhM^*rMXiC%_2~{wI2Jb<2Mo&#by~efeWu&~U%;$-oBGzS`)6#Z>(n3FO)L##PTi%R+jT#+ zj=Ea?qWv_Y%3gJ&+SpvJcauK#)4;`5l|2v*IIeZiNJ8z^G&UgTT*#8-afV`+;YP9XHRa!SOc$Zvj34oWqf_Ne*+s?|{uA z1cx=A7}V3$hen8t8TG&F_3Eo@ocpKhK1Z9$e@$K4bf0vBx>mi;I9kc!apOerbah2d z4J*~N)tg5!W1o6nQ~l8?>RIYjnH}(;`Yv@YBE-wSu}{{Zq!5eZ(=& zeg}qpJwxBDdhxjQHH!KU(@Wt8)hlgql9i}&gZeAeM_GS$(ki^h(aTk)KPZ1|M{5hl zfx_NIolmM~k8++`!@-)Y2Q~sJ<8y&8g%F-;SJI1eEAWTJw#Nf+Z&6G07+35bOT5}{ z?t$JjOn;c)sIJXDN0)cT>A))!+8qXd*s_+Pgb@Bt`rYw*MyRcIX-4Wi;XzIt_dTI2Tw0+@W3-csFsWH07A*5F@L#O4dzLfAtb!{0(ICFh)@c4XCvCWve3mxmB`je7oZkTvNGA?#AO6IZ;p zkY0VAkE|2bZFv$GMAJvfkEWf#mJq^yx#t}>*@eOo!he9z6Mtu8l*sxn@Uo20tz-0P zx)*rgBp3lB)}}%Td(^GOjy<2eQQ3v0ze_g-TuJ&)k}5lZ?UP~z)Tr8q5O%AdBCZSP zM%H^0+pYo5$T;>q6BA8UYOQAsih`p=R_b{Jc}7fJG*zj+xHK4LZ3S*3ZaJ?0hfgk?r-?Gozi$rRjEYQA>hL_6Ipiy7lsfXXy91AqV-K| zgUI><@kNt5ku@Jp7c501U`#s-2gSv$z%Lm+vgV^{Ng4qy$5fR;aq%<6QC4nbE!k+Q zGSxIdO;yIe@i{ZHmV7i-8Cy(MNsO#z5lvM(dnI6z$XZs>RHf7RGhQUJ zmQ^%W=_IDA92Hq_WSK=%mCnt87+LCPfkPesa!%*;!VG{A!rrbmbWM4uuSXO!dPFg! zM-(%9L@}dB6f=56Z-%xL!VGX5Y5n%cmbDZLg+ifFC=?2XLZMJ76bg;;e<}&{E9KG) QX#fBK07*qoM6N<$g3-=xdH?_b literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$CONTINUE_RIGHT$.png b/app/src/main/assets/new_models/$CONTINUE_RIGHT$.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca1bf9275b47133b1707718637b27fc8b9398ab GIT binary patch literal 1294 zcmb7EX;6|07{&u4(bOWPJX>omH*?b^Q!^96tHg^Vv`7pSSEx3_1FJ>SLd#57OjEHi z0~K{Ok5(kVoy}}VSF}DNHIE%l>x-sKHnItq{j;-w_nmpJnRniKe?5gU#4sz1jTSH% z%qk)rA7|8~{{V?Fa!J5Fkx|Sua1kV=an2x_LSr0=zz37EYhF+8m)WH_4!(Oc*U(w* zbmv86X8X_0ji<-ao&rj8Y_LOt0GWs;P>Up&?{DtfoQNc#(#9kxPl314ZbOmCh9Q-c zB-N3WFdtRVK%YSDow}eLuE{dg>4y7Oa(-O=6r{>IMn`VSx552O9#ZGFR#H$5wK2Y_ zwXqaTgQU*v7$rW6tkGZ~OPw2cM)>UoH5ZaMrL*%XHs@Qs4E>hP)!<9AW?6Kx1(1+j~u^2r|SZj)=#F>&O-y_nUEvx%8D*>EvHjHVsyGH z9zp$al*(>PIm>bIYNONW(H;WdyKbclp{988WXJaN5?;MIdUkF;F4E0iu8nOkYvftKK6> zHe%s+`L2b)MmI+1#Aq5|I=f@`De+K`HTruR=i*JG=|XA2$#V+LE1!Y{N+Lt%4jbY- zUbdP<^84lqY9V=2q~>&uB&&izbj&wJI0LU@(b2kCvWa*xB_=JY4xNg)@u=TQ}OURb94=${seeLj$o}i z)@36OmiZ#LzHMkqHTh`ow+K`4v4A~L0=O`nFZ)-UJR^2v=b`Ejh=)7!_G#_iQW4$vd}uTKRDd{Asvb_+g^{o`m>1A@;C@&M{=2vhEByd!sqH z)1r^|MX`_Jb)AF0;sKGNYg+^u?_8I3oLA8quhiJjV3uP+bRYN~s!xmc@KLG1 zG_`=sA3verC9+IzR~{dPpc?q`os$DCf!L~I{fS8P_I|AH9Gx_yqRlUh?WtwF+U3KA zuDqG+p=d+I2yRAx3lM-bXu5OF_Mijbm){7Fo(k@U8|3QFUaZL+J_YxF@O%#8bz@<-xUdrJPeHST?O3zT3T=F~jh zVmK|#)svOd>LE?{QalC*W$TE#9$Vc?<6bs-W%T*j35HfW65rF|eho{Ufh|~HOMdwyN>aL-tJPGhL6!{z49|~svkfiAW3X%gZ7^e1#hl~837 zQ6MNg*hmlv77<&GFr)+#MX;%&wI|f_j$g{^YM05 zg`?pB0H}JnQ~bb{zy84#!FkekybWBS2c5i}06>_hvJ$xw^fA%yeqI2Oz6}7fasXfn zgtDdpAk_>2rVjuBu^0eQj8d_$9RMhV&;qC|s@EQ3baE0tGA21H7SBmyfDr&-$034d zQY_-L>wAWz*7W0w9O0dULy?ijv$tkgz9e69e8P)-g!C>rCV&aH? z6xYw;pl6Rg#9}ds1Ol7Q#7OvkM2Mn)y4vh1Y?&*c{+{x(!1BK#}J`aSGrl z%v|uy)d|%2$B_)gU?Rnw%)i~r*Jf23l_;8*dp5HsdkPZ5a&yOA`E3kbTkihgX>ZhV zfeEh$gErK55!|jBTRyi~COjV?J}5piUAn*Z+31z>;@LXlS-SUa&+zA=^ASWehhrA0hg`gc!HkM23C-r;80S)DgynaZsFOL1>S zjPQ$b_3?8-s&#wM4o5?$tF9__(5jY$io1zXO|%AfgT7b_({K`w>%ap3{zhMXnuO3W zk#b3zC`ZAI|KC7O?z+0jpE(SLr24l8i`RA1+06QKYk$N0D?STq3tkt`&KDt!!dzxX z7AIRqFE;U3&JiTX;33j6r556V>6oyE^1msPjPBN=|eRe*+) z1-07^Gxj}&Sv@H@M2t2l0frt6HeNl7^{pIM-l|3LQ9`P!55~$bHIU1Vd7a7)(iq}q z#b=L#YU>b^x`ART7B}2DI6s|uC~5Fo0FJL2jBI?KHZ)#6=9XBY^Kki@&N~Vy^IP{JR3LrE z(awT1%&+CsO%;$tq6v5f`+U}fl;u?FQ&wDA<56eiOlW_`E4F?=5{LG*8mOo)+?Dar zd48(vL7{!yl{<63<-eLn;#Q5rJl+eXy{-ax-h6__@X(F1VK;7gys^()vcdOL@eWBJKS* z*{6%WF;v059yTB z%=pd@P3)!K?bk;l*Q`kb>xvL#g}d)!vPgyFH+Lfjk~AM5y>zc5L;3D*Wl8DCzGLsv zmloYjT-;j&SCk;ot3`7tr)EFM_O&MfZ|n2ToujMly_p*{QXRg(b5!)`sK;X_^L4_{ z5skm#R@GC(NA0fDCUI>s*H6&PVlv|I-m0nU0Ow!Yq<77snDoKLe<%-+P;0!lH=gq8-E5@1}oLv+qJAU&=DTloa(vA=#b<$im zDe51*ZmYw61d|)~zmK-w_?T9vz}0zqLV4~axpj&-Jy2?(%}p8jaAPKTOZ9=d-t;Xw zq|?(bIq~S`5AP@Z-J0_Chqjy`(R1{agSLdsGJX;}BP6HH3~tux_ilA-usyq(N6%S< ziq)>^J`!#Et|csuwteMV(hr8G5fW#DQCh|pR(JlaqFaNB1~+t(eB6;4(;-8=fV*H& zo&95#rxRgMvx0ZmOkQ4@YsZ*DCa{k3S>Z!3&tze8MofsBk;=U4=9VifqAu(i5OiK!9R?VO(0j9g&Tf237>Ij>BpeavOROe5U9zw^xSv4DG&OE1!RvF!8 zrk15ceUf+kZ;QLtB;OKtQjr&E=Y1iuwK#vO`~;%a8{n$lbOFHfV6GS)27-h^IbeE_(-#uKsDNW=9*}ns* C6@!of literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$CONTINUE_SLIGHT_RIGHT$.png b/app/src/main/assets/new_models/$CONTINUE_SLIGHT_RIGHT$.png new file mode 100644 index 0000000000000000000000000000000000000000..5294c9eec7b46fc0091e98d191992f6549c29f1e GIT binary patch literal 1269 zcmV7{~G7kzT}X6NU;xQuYRAv?_vhKoW{pwQSd_Rr?kZ z5kwF~E?NaGYU`?&wHORrh2SQ#9DG4UbRtMHFznaj4mQa+(wyXY@d+y zZ1o(O`WDcZ>H)f9`(2GJo<16FK$2ds9$*T3bsT20?dlo2z(W{Dg@6!3KnNiqgb)xy z2nZo#4(LSn08=pLfR0uVFa^E3DV5FkNlE*w=g7p3#QAzo(h*5Z)q{*xuWBAD+fPec zl=MK?{}w0E$jmdIJ|duismCJ`P;109LqIJM&wqOLglq_GKOyP3isIo(^nk6zb4;8( zHxbYsS{2WO)wA>o0o?)Oxjh2f0P(DkfYz}R&-coW=Un1mZ zL`*&);)$7bK(_aactR!{P)G4x(uCrXCK}MHc=jZ2JGpqI2?o@0Jf{=)9E3>)L_GN> z6A1mxAfC02CLr6p)LlG3C+;~aqX?*@crJ^0HZ=HvY~L^GTS@y8x4k0iAn|N$@BvBs zM$%J>`z=daAf7uj=zwe=m2@z1%Vo_@o}Uu;Tua-pAU>NpM25izWcxGa{wCPG;*r{a z1@RZDQ%sfZcbx08?I-7a4JS7_W&%Uk>V`qDd?H`B-t=RsMc+iUN!?yn+9&DQJZMH8a#dFp6Gu79GIkNq6 zQapdzexdq$Fh{l@wtYPzp1*A$uD%}3neFcq;<;fv^Nux!!1iki@!0lz)z^Xow$CTT zbFBJ0P{8)v3Gw{y*+*P4CARNz&dc^!s;>nFY`>Kd&zIHLF%`Y~=^)#8NjfiScVL@q zk{)WBW;tgntfy}uD0@?}cqHk4;+ZJhXMzu1zf@lXir797e&%DpTzwrVV*B%8JZ(Ry zj-j)Cw`cE^NAR+JsvLjYg43r+UtWd15nTU4$`shN^7}xxw@bPj*kY+^n#}*!j7{jn z33Mp9{;QNJ&`KWyS_rP^ZHq!f59oN)G-t8~!RD0)wDSCCe_#tvpJLS~(4pWAUuO-1 zcB%tf2&_HTG|i=~LC{WhK+gx(E@lmZ_NoJle6!eM)(~i~>_(#Potk}lcU!x82&-3l z0zDR3dy#nhp)#Py18aXxn*t$24Tw)3_C#esj|SGBN}B>9l>zMttX)c*0wI+FZ40bD zmo^1LDg)XcSo>$%6bPvd=)S<(YiUy;WT*jg0`)}Yo#-2CAMm|R(_GJ-2kle_cu@pObhHwBu4M$1`0|WCyPZ!6K ziaBp@ZR`q3mpJzE`B_z#AP=t7cRJb{#CD~1$4;{Ln0Uy^W1*{qK$F0QV@ja~7n77v z3Z1yuRw3!ROC+*3xWX=$=kU8XpXU|tGyeSls`2@{Gk+}EpRHj5T89K01XG{gJ+sI9 zyX6LlnU(7IcN>4N+@K(T#M#ASzvxE+!EXM$oMGt3Vzl3-M3tEk=#?GN0}Wf)OW6_kWzZ(sAoK{t>f90(;z9!CutyE zQ;IeNRb+7OoC(xyvh2*CycYep^Jm`MeQJ@?uZ(xhbFP0lSQl?ot@E<+<3IVfUa#-d zMJ_5aN!eZaeRT8jN$Whlk{_qsxN)mv7k|c?3Z+N!g)@1xqC_ocK6LvS;hS#^y0aNOa3le%T--f zt#)17Q=hx+REcPS%OA~`6D^B1GR>9Z#AQ|bSh`$E!*;M{Vw)N`{W+#T-|r+SNNi2&+Tp& z-D^)b=zYj|;BcwV#e&~Wz3^38**)#RpNpq^#j>fa6}_1BD6_5OTWOigV%w^fmvS90 z-R@9&RP1>^Y|oS99XFzbfR?4Wyz#8s^GMZy`9H>z#i`HY(*8}HS)cx_`^=u8E!F3L zygyj&n*Kw{xZmjW`ZIrQjq}6aBr(~tY)Of|f9QfeQ&Ve0f}%nM2Zz|;WFlo45cA9% Ydy6FtW}JC^UFVdQ&MBb@0F;riQ2+n{ literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$DEPART$.png b/app/src/main/assets/new_models/$DEPART$.png new file mode 100644 index 0000000000000000000000000000000000000000..9f7e57bf6bfeec94a6cc75072e472d357b5f060e GIT binary patch literal 972 zcmeAS@N?(olHy`uVBq!ia0vp^$so+Z1|<8f_e}*-EX7WqAsj$Z!;#X#z`)$>>Eakt zG3V`_{oNwvGRHnX7v@p?D6T2AMQG{~`9^^aAN@V@)6Ujt zA|kkTf`}pu)4xOa-I@<}Ea8Y~IkLO-zL;_M^VH{gX=VF1-!GmYZu|M}`E#2;pSg4A zo@W{iT;uw{w?R6>`fX&I)CRU6Toqh0r3%4JYuNmlibb9^Tt2WX^SoK`sjOc$jsnWe z4`!U7Fi&U2vU2CT@5)p_3BbKFvU76JXkdRno7gg1A<^? zn6$|Cj^G0|?v6b>HqBbF!>wkbLdQhLf;){m&C{=biC?7PHjgphdIHyy)yuR#ACOG= zyXAg$m`A*CDBA(fnl_Oa>u0Unv1!T5kl?8|*Xb+^_YFqmetD=D=)l~yOVhM zYx?R<8tVk_U;5J{!DP=Io}E`OZQ=ddA#E{8IR27eNAv;pr;O_!t3P0VAas_wa<6vx zqFH@GA&$b%50o}+j#*wN@$}p6hR-`Tarwmg%Iig}4wQImH@hI!^T6x_iE1mBxxO~# zTYM*f(kUypJ$K(v^k%rhW0P0G5VsO2vz2S{o$a})wyb4K?ZWbx)G>PAR>{rTU^}U9 zVu^xMUYVtb%bkf^;xFy|RQf7PJu`dy=AO&$68$P?uip{#ELV~3>DaB=*4fcM$!>DV z+JkwYC&?|Dk-pIG&=2QJ<&);=ZOI>&>D=megDS=x z#=6*NQXfynUKYyUx-YFKGTXQyab{^AgY_;;p_vT#w3#FSSR}szO1~}t`_x|6`8MEdv?0fjsc%|ddlYj1mOem3Z+xhHV(cO#eseC`=Zd`dcciZMw=f%4_ z)DI|%%Kq87qrb~T@(r4+KPA@R*5i88EoKweJ=!nVO3gm!dgT7f=Z40cYkqQbUgK_`D2R$C zPW_RS)xE^(fBJ{{9Y1ux+N7l!r>MpmfAe1TnZ19%`;m!PKA$nM*Vqzg(bI#B)*R8_ qICtuo4ads92lFSvGQ+oB6^!m(o27o{mYxG$ax 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_EXIT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_EXIT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..c4520c1f28616e72312318166bc1409e7fb3f065 GIT binary patch literal 2616 zcmZ8jdpr|rAK!8tk=Y`*xgO3YY{N=(zfE(S-1Cx|yJ2D&DTc#xtt>6%ZjupooRGtm zONWT22qBk3uTn`Ds&}gQyqD+md7j_p`99z8@Av%kJZGJqY$e3x#Q*?+1pcVC3*QFp zPLMEvEimf3$Tz@P7h6j}(}?0K-#;Ga=0){#bif8sB6a-(DWo7>T4XdI1ppY+uzWW% zi0ZFGi;Reh#nMdFz9X=Fe>aU(Q~3^|l1LV|9BzAhyu1c^R!KG$;#s90AADw>B@>?|(Ge-V>ZKh%lcYZw%0D$uF z))sCw;Ccy};qES*8N#`Lzmp1!({{`ORY6)nkgB0c2|Kk8u%NVobBb8nN`cwuMzE%g zx2R0wkbRiE*u~(?Vs)uvOkUn^6Q!Mp5=+Vw4E1lujhKcs{`p}l%+8UVDhMjhI4+(%XlEtKcxC5kA(b`(>8;bA zAeqOQfY|H`P!GBMhEFz-=U*trclEfC#^r>Ci)Dj5w-5(K zEr{cXFhVw<6Xc9!VO@e+)3pYHg{to?FZFlyq2l#ey+x|*9UQRG9UA4qX1NpiD%}kGQEe(cWP><78J;LGKn$z)Sm-_Mjnn&Z<+LMgpVr$lF=fnKhPf*XT zW<9^$$kq`fD-g{_{j_e=m)q-T}}PwTX8cXRbHn^@yjz6@Oy zK%p)FVGn=j9T~ZP9u!1|PdKy>^t_no*uWN+g;41qw{e42>aFJOv($yY)@f#OhpW)U zWA*BsJgkjWf3o3))bXIC>LJemI){cYPNqv$!L38w46Ir|3OmG zPl!xk1%(aVk}y16M;iU)zDdM5uOWgukg8>M4r+V`^crQkENt*$O*fDu*?{zXeL$1Y zIBgFrKtAj8@U86sat}&tv3sNhZ$%sb_2tR@8fiIpTL~sF)CKHwuw;JG+Fx$n2fjQm z_s8Hvkr%$Bhn1yk0|Ziw+6UTml*PaId zB}Wdt(D3L<-PNUI70eoZlF)1A=dC2%w$a%JI)DvWZ^P7SFMlcQWQW(EtvoT-Q{9;i zX~}A3>ib5Q-Uv%?+xN_Dnw`7Xk2lgDI{nAUUO0-|>}+FO;-CBH%-dgZDOHDy{Wk1_ z{6=$zS(GJwuEl0tjep9;_?VDHNcFyW$KFxg`imKa1ve40D7Sz)V)8V7ZtjG*t$6e1 z_#*3pyvJN_`AA_*$Yo_YP^HFtiTSD281~(6$9b)QoQF2$2CWt{N^q#E}J| zfx<;}sZ56z?bXxgdOxVj%MDl@3x!>H;ruL^$n#9BeyUCuJJ zs!T{pfISp-+6AM=e4&v`c0Fapm1$Nu1|jR~lT>=a*bitLm?cIhhd6y>PJG)WWV59w zvCYyJzhiSE4_(QB>g6Q_LNibCdIE{i!Y%0}Z&aje=#6)RpZrfKFj6XJ8Dwc?IjVI5 z!H)4Oz3V2b6>4Y)(y=%g`T22-hI$~S)Lcso=Wh+~n~{vbWhkwGlHrJS=mrli7YAw- zJZh>fz$5Ed=+dYni+!7kOjqR z-#k;8ad?ZfNIziMbINPY%`n?pt6Hk5D-^HvSCxTceI-#9G*%ZYPm^K*TnoX&<|RD> z=DqeT-+91NRvsiOOX1DRq|E>v609gI9N_@{=(M4MR%}7YZaVskW1GedMT{jPGMs0+ zfy2;}9^vMK5i*3(E7pQ%mGoR8p7ZZZd3KB8^}FQRi27`c5Dc;t$lk+yr|Dx9shko* zPo#QR8DdE8YsKO?fj;ltgL!U!wJd5fWGEX0Zn)#}+v>das|O<0_MfgK5MWkV9h+KjM+r}Jk_VNuQ@+m+M#WEi3C#`aY&Kl#h7ecLjg;jSSNqP(e7?>w|g zVhm>9T@MezzVb>1W4E@73NALI=@=;Q>d~c&;hGlh z?KX(j1LM`n_R`ixRCTFq>r4V7Q#8vcI$ZxGM_AdDv|%<$0yi5AiEF@%m$^e?%4^lgcW-P}OZ`3^EDYoyphl_XF%fzYnPhQa3ni*#pPQJU| z9iy7L8lan$`tjnTRkR6gniK_2^BOQtX@O|NYSa h-@E@KbYs!K0ndm?T`RP`RIvNU!`nDnH(3(X{ssL&cv1iW literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_LEFT$.png b/app/src/main/assets/new_models/$ROTATORY_LEFT$.png new file mode 100644 index 0000000000000000000000000000000000000000..17895842ed4b897d7b02b65a3d867c743a13f482 GIT binary patch literal 2126 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_RIGHT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_RIGHT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..ced05a7cbcf0e35445314ddcc54c92fbf99bed59 GIT binary patch literal 2869 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT$.png b/app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT$.png new file mode 100644 index 0000000000000000000000000000000000000000..de0e1c7386a612fafa421e0b7c60b69c33fe94d6 GIT binary patch literal 1878 zcmV-c2dVgpP)Z^&L{9mhY{^K829*)uK8(2A)%LA{9n?1e1R3N#@il~Qu6 zC=-JOiH3x4go@}N1z}k)78K!~js7Q`Q)-0QIxs}^;{~otJ_oo-vdB#1r zp65E}KIcB?zMty@_lvRLxqjC<-*f%0>-t^4vq2`4$z(E_OeT}bWHOmdCX>lzGMP-b z32k>^7^neQ3%m_@4KM|)0#+0zM}Z^2VPHS7ErjsTVfS;a#Zb=yJ`Q{cxEOdXa2Bwv z_)Qk3bHIt>_X<&v9l-s-PeKSMhT8FQL7h;~S8rGMs67YcKkDby^V+_*kwTqPKchZX zg9!Z`S07bxHjcK;LZ~z9AJl_23(?O(^;haeZQpMvQ76^+tGgN!;7sgP*Qv|fzW>gk zu2SzZ&JDxnCG`$8pl(#BEBHHC-J~8XDabud+<&J~FI0DwcqseT zPt@S|x}vSru(eCQxQ1KqF6su;N5!mqn=y4hsNd!4=hZ`rzK=TYdkDeGfY#JDWcZWeelgmA2(eteH8_+m^0r4OS7%LVx0bqX!!3O(r9N3#^Tl#o*RK%EE+ysb~ z9Zk|BCKyvlS#X@fsEBbm(XQzVj%6i$yi~UFQ4!D@{L3c}^YArELgd2k>HwDXBW3~i*WtgDsBbnN@}%;Fy0!+t7g?@$cb|Gy9rxT>)HUkQOFWc0 z^*8F9D*BsHFH!%IuD=@3T`C=F)l#ZsjHy=w@8s0fvBdTE??VXB)ZpiO;76pVr+dJ| zz$RdO2q9^QZaf&;0NhEr9MddtbqL{+64%s+v6|v;^zf5i4)*0z!z)q_k2nF z3E&c9(c27gSbc^#!Oo{y&H=6gZY6$ZR`!8P%;w%TNTRY1G2TkNfyKCd5GTfRo38-Z zR=B)B?L7s&>s5dMZs01auP$eSZv)R&ydJ1Wj8%#4qzHCKiaF^!z)hs5)92X2xaY6wmD(Torl?S4Ik@Xfj#@0=KYtEMWUX&W(zH3ghqXTJ*mNK6<$)Ii(a5@W#7 zv>o^`aUXI4u~g2t^vMAwb1k@;In-~oFs&>8`xs}Qt5TX`l}Vh5Oy|Epjj4P z`VNiO#ZV`SWs@JFe4Kxp_#NG8Li7_t*h^6$P=vzC;x|FeAlz2cZzHrSMiH964}7fT zr9I*taeWBk?`1A5_5?kO(V!kBhPu{iZPQnTrf&c@RJi;p;FhvNbe&d4Mh&6q#&Ht@ zS`ed+&@?IxHB9Buv@pXQ8Oz9_X+ef5#yg5%8OA;|_0#DTI!hol_0#&MZvmD>XzHhn zVl1i9)K3?~)RGEK{d8?)EVMxYF(!zGWv?zSE6W^krMe-6kn%l8r|9AYJ_wV*`+$M}@y0e7H!ZBw36OF|J~a%nCICF{mNuAnM@{=$z(E_OeT}bWIE6P0KT0?Owjo_ Q(f|Me07*qoM6N<$f;s(*`~Uy| literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_SHARP_LEFT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..49acb0d25280e8d07e998fd61542bd930e7f4919 GIT binary patch literal 2826 zcmb_ec|4oh8vbGrjjgeyBtofu-zp*^qHQ`QruMefQnd?75PL*xi=so(Eu(Z=sx7*x zWttMp7)vp9P2=V@NN4Ryo2}C)06bC$fskp$4J%XIwsqXeCP=2H^J)d(VUw=JXSOkv+ z0B9PD7l!#$eUP-U&~OThW~K6tf#St`u)YfN8-*HTrQ&Yyh_oe<{gI}6CVB=c7*Qk= zi6);rk2;Az@^?CKWu+2GrADCi^zQ5|E2A%)6Q#j@Cws;Nd@9pRt z>KW+&qs>c2@1ZCnImn;qyr+*bM1N!c7xuRgT7S>{KZ^OQ({CuRRg5TF|DR*Sh@Rl6 zdjJ6VECFxhOam?7v<_9YlW+6G`>3kwTyrn&_$f;auXv#eB4Fc_d5B6ls&ydCc~Dgs zt_Epk91;QBIZNSc6bhUVLoBokUqZh>anW*(WgIdd9!-kbU49XJF!A;H$mjFy*tN!+ zBc79=yJ2dYNWt55Xdd55tmrY&|7jtg&!_Dt8m&`snh0G{R{RwQq*t58vw$)_5JhF%>5UO~iG zdrr-1MGqB06*v|A0+GU!@Mw58aPND?70GKv?=u_O%5dclI2K=w`i`$0_g0FNzfnrb z5OCCcK9VEP`dR%ZZXGvquU0(-;o#c@7c{h<6voQp4>{P_hT8Cg(R&>qeSNKTg?7o1fgx#sJD`s-72`O z*lzxI%(|2Gxc?n0$D*xIuSvvk!}hLrptfyes5R~QuHHUwJFW9X;N~avW0+y9k?m(@ zwY|a%S$`#DVZ3gqhaBMma-aNU$auBug9+u93air*ov&bdbxBvR^u{VCU#w$TS2(~+ zwB_?0e~e}ik8Q|L&7A>B`}t)n|AyfhhU#}#J(CTW3!4L`IUkB?`$0Zkw z><0o|;W}z!lF&D2rMK=Vvbvv@qLQ(#4YoGW(%y@XPC^+mR_shtlSG1c(5iXZSdi8b zHz5Nfca0#8JkzQ9=9CS1oBv^~QM|di#6aQu1Lu3z$8|GAt5iV@@q~BW{LM3J^Nf0X zgF8L80V~uYAbxaDFwwZcQo&XV3NDGKty@KXLo^Ciuo$t9GDh4EVzZT7W^-$Z zuN--FCZ)H;)HU3rNnI9nPBS`>>;5xBph5$yW}B(jrtL_dc9N;*R_A`M;(D<6V-tq7H z%tx3u7E9ZErpklRDy;BcVP;ENM|GF?axXgkB+_TShq>0!ZjRJn&=2!<|5*O{ti&WE zBn$YQw8i-98R>(64L=j=cE8ryHNJfnPX?wzigI}vX2&H=74FWmeOIKHPEw$WdpBi* z__4AF1`V+kxuLb0X)SS(M)bLA7>XjYt&8(6W*>H;ZysudU=t!}kXl#i9qESxUq(wL zCkr%OJd-obU~Bi;_)238>BEm9$a>9eQSYg_;g#S=I#R5~Y9sXebp5D&UoNfB&d6y< zrnmNRV$J*JlRp5kkA>i?EsvKR(&v&|o08;1O@g&>3fXhPJwex({1a;{=AMLh0w{T{_ErG_#YUnL&obztq~Pci9~V%)74M%9WZNEvLw}S7=bTBxH7l zwgo@QErGYzwQDb2bo+V3d(KDBCxNr06$&YAMzrAWd*nDuB%jF|ozmQr5y361yzLUd zytX|DH9v(5y@p>y8Kt%fsjdFAR zxPvkfMEjs1Hg%htE5Nz|bEAtpHhXyy?uW?%ZCT?L6PKG?FbxSn?$j?8%+Yd9P5Kd$ z+^(tp*WgW*d2Z-p{yuDGbIU?yet`g%p^o@2|0^X2KQ%3rKH$1;N`$o$_zOhP{Vby* zp9&O92Mca$se~kJMthl7d;VchhCsoHr2LfkJ?!)-j7tHXM)za0=4E&lwN+-%oSZwY zghMWFs&LjYoRNT)z!^oe$tKKHr0~L>pw#8}$~g|<{g(4?l>L&U7N$d9Iw@(JUy&@7 zx%)D$BaW$SWr^Fh7>=n{uPzQ!xKicP))&M2s6J-qeJ^-1zvvhB2T=)uX{m}^Z5nqU z3}_P(Zm(pQlhYC$B1s&tO0Ah|0cEKn3J;SW2zNY9(F5KpupXIZ%t78f7mFABgj(_+ z7V6dnBh^P7*jD`_n|)Iii@|bAw;O8xW^=dnLUmSJ6`RTIp1emwQj}9fzR~g0q@YACa z&o}S5PdN`dA49G>B}(hk4+ycjPX>sRM41vzYvFtH+enWupB8(NruHS$pf_e2%E>kp zx{MTBkSIk_WYoH*4?3&yWbDoZ`km^aT+;dkxMW_M*a!ldEPuE(VF`kIa)Zo~^gCAU z{&;oznCb+Da-CHKkQD|z&7UpAF4&ar6k|BH_+3Pq%WtW8?fOF=n^JL6U4ksay;}~1 g|Lv86Eav;l-{H$zOZINy+k3SV>>Th9ao&tS0ZaSHOaK4? literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT$.png b/app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT$.png new file mode 100644 index 0000000000000000000000000000000000000000..f2f7b2dead7619703293f85ae6fca20af4fd9e20 GIT binary patch literal 1897 zcmaJ?`8S)10{z4i`;xJhQj-dyp%P1LPa`3VR%r5Q6}5LTB_-C5Q7Gwx0O|-n-}Ad(XM&+#m0`S=37|3bI=dD++25TC66IUU`nwcRCb&5QvG(#LYfh2HDcFtGT<)$= zGTckrSo(hB;E2S5cke6*9+n<5w+E%9zh*1r{-1QoOz2>BXx-2i6ib(74*X|iXVB@0 zc{0TSs7$X4g<~#he0vV*t4FtouGq00^0Pfk(JU2~y-Gp^Du+u2ag@$%^2sKPF|<@0 zbVba&{*5YvsvN2?tj7>I0RyU!90=02yfckI^%Ynb9X8_2gYq9*25AuK)8a4jmU^Zj znk9sHl-d?p6zoe_aBLh#ufo7ZuVyn%};l+G2n>y zP+BbCJXlh23L;Z`1DvORiD*&`r7=&(Dc32}xoyOQ?`q(9FwE#_?Czl-%uTC%TJ|TN3_$T3X2R!2StHygvM4dHY{z{&v!fe*{}d zNZOSJ!+b(M6=CgCf=eZaH-1o0V081(2-+nU*?#$=l1%vr&mlnL7Lf8vM8)5jx1(&TR&Cn{KML{k#Cc}$z=MB4@laC-cC^s{3TkedWzGoDGHB7 zEJOD5rgsu0IFGi6T$I0kc9CoLReOxzvm&1bf848*URy;lBYw3`7>St{&GRXg?px(75#{k;FlJj za&90>e7vv+?-j7Bw+KkqU=xs=wN9k=E)XsOe^)0Bj#$mXkwzs}D@Fyup1!0`4GQXk z@E#G&$AMx0W**NL92g&qs3;pJXa4vi%|2ST z&N5!s0^@L$?xO76oOJ&;h$W&TuR|UVwf3&2KB+s@irc$gb};)!CBh|f{(9sDirET@ zm!Xr_WO(-E9K~E0#)z?YB&hq$fa*twJ~|*YZK<=S8Bw;Q2|y&|Z>b#SMZ`NKFD5|T%#Eyn`<%A#11zBLoOM$g{(wH}sbYAxO6GH(@5Y~g;!&$g+lR9v8Sj4ymu#TS zkrG(vAy*F6#5+an9~FZq33NxPT^*K&dTyxp7-fC0+&gOk>u<1zPQOQ9Pf_XPrHHL) zsoxE~V<$XsJlmGj*=p3@u~)en*de0Ho2fg-Ovy5hBd6arP z%)2JQ*NOQdLVo2e?e~0_#`*A}*Kt3;A^>N_wO^nn85 z8n*8}Ah4Nzr78Z|=`U>u4g05M0ThvGx#0<66d}qut6ceW5%GAdmc6z&dVb@Xj0KTP zkj5k{K?W1nDq1Jk-Gw1+i&a8MMK>mhiOm@>lT#DZX_8rw1N!22n9emQs2m{(4qv!_ zf35VAq5ktkjAgA@`P9tf@C!=O=Nr*p5kF*qYMGT7UT7T3Ub;21ZbmV2@7c+#a_OzT zrO;WsT8yW^7TcY*AZa_iO=|NI#+8kJqeK_f7iSaQs~9j^cLPtmA;P=ueFHD0ju-lU zmOqylxM6cNFJ;21!yPs-Fa+U=RfWIBho^y?Ipd{rbAEVAP{OHzCs;meMwfL*?33(@ zA>f!fepVr1+*Cy}jA#^j?PeA^;nW*WviiK#NX8F}Q&ag^P@N5%%zy}3Fr74rfDO}O zLo8XaNiJ5Q8n3204j^ioHfIYqy)d zkW`6&eHF=Uyr+H*R%J64uZqO*kBj7C3vyL9P;xm)7C z)7m6kF7|NdqvvLyRzDsJt^kLko+9dDymTmTLq1gx0T{OU;m^Og#C9YX_4 V6u$J#3?6?cKq6eiKgL~8{Vz5_M@#?! literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_SHARP_RIGHT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..b4ea0bb936f0159e285bacab84d6e204168fe3f1 GIT binary patch literal 2612 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT$.png b/app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT$.png new file mode 100644 index 0000000000000000000000000000000000000000..4e49ffb59d0dd421e2aec5dfa9b0bb72c3e4d8d9 GIT binary patch literal 2051 zcmV+e2>kbnP)G(f{C^XB}NTT z6KrgvQ9ltM@s*eugMI;DiGI;YMAN1vEhNSm2$W(QwNGCKBi2Go#nw{VdGy}DAJ)0e zWo9mSpU1st&vgHi$z*2E-h0jY-@W!;Yp-)4kw_#Gi9{liNF)-8L?V%>2P@lwq^p4& zE3l<36Tm)TtC>Atw=uOK>2r#QGm^GST3YvgDMF)e11hEod=U6R-G&rlwuu379OJw*f_%tzyhbk{A&&Tg4c!+khg>Rx$R~Z9oy`)NMe;w1GbZzp2}hBE%v_ z8`uTxDbYs@I0QTd9IV2qVH1lO2AmJv4Ln`2k2WxBX6?$X8Zt47@mAnxz=zH3aLxAA zLTn58N??nm_tb4j9mFOEz?H!FC0$;(A;Ts{F&e-sV3VZR)osi$iBXIWZwIzYdT-r^ z42zh>02k!mbH!y1Q;glfM*KuBlm@=2pA#-?m|{!-p9FpajOA>5PPnY0x+ya|0el(Q zRG@jsWxcsttKwnkL7$l&lXNqFBDXsG9zw@uJs{}@GyC`C3nUq^09XiI0jvQ=fLCX~ zpO4Sbq2pcq-(#gcxRk*UvV);dQOsoxgH`wpxp)wrMF)wEA4%!sCK>nc1CYw%g2(OqXji zvoSL}XlB1Nvup6#cMx}BAvA!G0F@;!s}N(H{x=ESO#~xpE^uAvM_>y+OV0FYG6DPu z_?VgP%`;ZUeZWoG7@=H*@BS*G3NfC>vz`5TB4@uVfF)f&j{^@ged%Tk_zrNFnf){8 zH~^TL%xov{abQYDxK}gaR!J8W8FMmKi1AzCLEscqr?~K&_$2Vt&MSGv3>MlnQq3FyLs z8sf*Sy<(ki+T<%+ot7BIXc3;r8g%{bHTZ_2A1ypxUyA6&$f`w75H{^!BPryQTa=pu zubTjllpQQOF)~ijJ3HG=19;mY43M+{2u*RE21=)6Vin_g!V3~sR$U;FB`Vhf%L1Dm z1^!fa+?d4(Jw00lT$x4gRj~wEhabm=@PwJ=eavABQHo(^H zH}LB9kVI+=Kh!EslwxG;BD^wW9n*a9(Z@v=HN5#9aR)SbQAlU0i3Pa=v1JDG9Q0aPn8INx!BEB3js4k zjEsH22-?q??Q@|g9^=7ueqCWdFW5wuTW=}~vgr~b#0B@q$yU^Qs zsp!MN1HhK-k+z{R;ckA?%k_ zN&3AkGjai+tt2rbB8d?ZNsNd{Vnjp|BO;O*5iu)*z8)MVtc2!S{0XQ;B9TZW5{X12 hkw_#GiA3U@<^P|K>5kHv2vh(7002ovPDHLkV1n^Qy@~(; literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_SLIGHT_LEFT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..fbf5054c8b295dde3bca1eeb82cba7688e1d63d3 GIT binary patch literal 2688 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 CSFjWS literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_STRAIGHT$.png b/app/src/main/assets/new_models/$ROTATORY_STRAIGHT$.png new file mode 100644 index 0000000000000000000000000000000000000000..f0c3891ddd67d1d6b0858083e5f0c2f842e963a7 GIT binary patch literal 2158 zcmV-!2$A=RP)s&bhap^GojA{yhJ)*Is+=buR4Zs0XRXsRs{wEDIWSM7>OXRJ}r7H0UucND3jo zsqQfGyn0nDNW&DS=~FX==rEyvtu=LEOj9p*sy|Q<8uZ+U3hOsby_itHWoxn$ zHfNf8(V8q6h-vD@!ZukB&NTI6VVW${$$F5csTT{&WSNAx%KlcwBkIGMWgk=T>!Xi_ zVX{o7>9fUz%knSveD#*h@^`Ces{ibxuLIj;nO4LV>VNupIDc2)S+tWaMp6D8^?^S6 zJTOg`drVV5E8-D#-Hf(MiBZ%!)z)O~c3&@b9;Rup_DYLU)H~DuP1ZNm#mzps8cKM;Vnh;|Pa3e6CQT8F=qKLS$ z&H+WloxmrH{^mkp6Y!5Z$J7|=iR!&`*yaE8nr3OM?>(bSTWi(7W$YJcsZq_-7y{Il z>O<;OmkICVHOIQXk#-#7Ji`O(u8+shiZ(`kU!~fEuP1@;!B<`eXHVCEKW6jH2B&>ecEU>NV=CJ&;UORhSal#?&L# zJ2S<2Kz+S>g!@Up)KDMu)e&GEI1yM0yaIStX7!VRdq`f;-RfPyuOeb+9b>J6plYn!9!yD*w1b74RL*PjD znuwTepx;>;_{u1RIGMB}a)hwL?hga51U}{v+*u4%j6#T0f%gKr?&n0s!x#g81Y9;~ z7kJPsV;ndOD06Z1U=8CK1HJ-WR72a@3``7lDXF3^YTyHu z^X3Ge1~vj)ft?Yt&!v_6a^NW7G~nALamvi|CE((S_*scMmC(2tg8K ze;*OMO7wLY@Lk};q*Ht@_W`Fz#Euem=FK4Xj8(vqCCYCj#guL@BLqN1JPTX`e1^PR zy$<7~uuG#fDn_v?jt7=xR@nvIMfn7R-4wR}rzDfLJ+s;p;2r9r{r1}rO|Ohm(p#5f z9tAc>#GmK8nMTBPL|g~_oIH;!fH#w}LK>rKF_x1*!N-9+D(?Twz`dDeSC9ggjnT9i zBMR z65@rL#;_gOK;GW5s-`h?r7X*tG$}@IczT-Z!{mFjgZ%v8Wpxf@CQXWwlWPmOUYlUPuDq+nKUWJPV)Wx<#lEA6}ea|$h**biS(^VBQz#P zL`(zEWE34Cg~03j(sU{CR?-Tbi)SLDE*E zjNCBxq2xcXvV4`i_?W;=HI1PwO^fj)$*s)c6m?~loflWVx%U)1fIn8*|6DXJ#sq0Y z%n3y-2HvMulGLW20DPZ3FG}D6>WhzcrBN}8P{hNesB8|)fOo0O=hLq`4qQ!s!t^9? z8wau&1&@-#5jk`|3HYFTL_eLWYk`}AcauNgZNLqM2iO>mixCmqNf-XPw|AX$!Nuws z>eAw@&=Yl3JzBjSSP#6GJXe-tT)&Qp+%S7(3@TM;32-5BblIw;yN)d+XQ0D0>C=H_ zz%jsDQl{bwlz-tK1lC1FV<+zpgG^#OhLl3nPwM~Sz+2dpWg=t`> zqi2e43|tJ@eHgrzlqc0xe(NsaC!`fo`#OIz+^TdJpgz>D#{JsK?v0=;QOi z`lgecXJaT?Q#895V=inAnY-uhYu6rOYEiElAEiElA kEiElAEiElAEe8t!15O!wds7^vCIA2c07*qoM6N<$g5QZ5vH$=8 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_STRAIGHT_INVERTED$.png b/app/src/main/assets/new_models/$ROTATORY_STRAIGHT_INVERTED$.png new file mode 100644 index 0000000000000000000000000000000000000000..83a68511260de3987db3af3bf6f2de09e150820c GIT binary patch literal 2866 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 TW6QhE->t)5CqkpG-|2q?4)^lk literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$ROTATORY_TOTAL$.png b/app/src/main/assets/new_models/$ROTATORY_TOTAL$.png new file mode 100644 index 0000000000000000000000000000000000000000..f2075af00390b6a3310f3995ea735e5d2ff35d26 GIT binary patch literal 2096 zcmV-02+#M4P)eT-d28Hb;t+YhlKv{H&_X(578DM})-Rs#m2M8ZF65MyFc zW5kab5)6qNjT(&-iAGGY5=kt9@C^!y3X%|OLy!Owq*73WqAiuuYCm9iyWM^KWA57Z z_TJt(r{~=IS zKBSHp6rr6d^(pmB>hZbnZC0V4sotmVIYbfK1sPTUpngD|m9DyPs0-DvsuLB8(22e3 zwd%3C?|C3mPf>66&|Ok0lj?8O_t-oo`%zb`o78=M5@IILtCy-rKpq#7Fj1O6t<|RS7Cb~F$Mrr`MY{@#r97y-9^5lex^$M-N^O$y)Uud1aKqpe3iyS z2%CZLB{p9GoS}|X*@sT#662i2b~}N4LI@Kz^x+oZZwc)Ja5C|orB?bbhB_ZeeY@QX zJXS|PLI~qP>e6*7P|2KiFmgN@MQ-fA5W>D1`||U|c1wU))z}Xpj~EMqd5LYGuCpV+ zKZqffUMvLW*4&pYV$3gKx6+Bb0~5fGgm&|R+LIUt{bgoqNNgmLLyR$ER5XR9b#??8 z0gg#%H%fY+OOr#4SAf(>`K&rS0xT!a2fY|2z0ak|A;vbMASs-y*13wgD6!p(r1!Zr zeHSBy@G|gRV)Ny|*>&_oT>xB~*nBhaavlAcNv;X};ly@F10Sj>6mc1lk}oCkO?`I_ zeaMe-vuCnEps>;e0rk!5vx)Zis2{7+{y?D~VN9<~VM^W53ZqnE`$%IJVd@U!7Ij4x zwg(ntGINnF*E>DL%_Vid`l*6;e^${g4=%=pfkz7r%D8%idO}HiE7Ttvj|Zf(TRo-f zdmlKAuIdWYcig50c|!e&nj9-q&r=_>cp~*Rb&kP6p`N5ZQ*eMZx|s*mw;E3|b-MN( z<3xQ^iR(`pQ;1IL_n2fw{jBLLt9JgQe!RakX?+{j@ws&_2iGBN<5JH;Sj>EejCp&20#d52k-^p z@r>ONcoMiIgplQJdmzLB2q8QHe3baj%)vI`O5jhK><^9@03n2DfpdXh(ua_Bi%DP; za83x}{t!YoS2<8(0E7@;0zOauTdvb=1}+XEZ0eJ}uJm>3R)Foq9l@%33Ah>f9Wfc< zMBp@HN>FwNRg9|H4y*&d-ZnX>hVuKu;ULDN#EE%*2%+|U>_cJL#drp|EQC-?R$|rE zCWiVt;QhdxfJcA_`&`*(2XIBZ5bANj1;j1gM~D@7YTw_^hI+bszx($M#*E?bq|_Vr zD0O3E9O>#V*EnFMXsm+p(2RK1n0j67i!*!}4^2Mpfx*A&vJgG1*;FA$hik63bA)(Y zy~{4q-&u+AJohROezJ7Zc;Kw|Rfvt6#GQV^OX3_6}L^Gad`;nwe3h z7)IBWa;*t{EYbOyNluLtUf(xu7kLPs9(@Y?F3hP~YJHhaOUyRPQmS*`#oXn)I{JCs=7WmUzrYnt2E zuXzr8J*iHZ&t-LVP3i(;F|fn4NWJ}cSsh(dONg%->rO4pH6Gcqe=ciRYrxxuSgiiY z_=VVbSc?IDaarT)cWpaIZhRuHa{mdYMhvLcWsR$AZ98A#e%Cb9UL(ddMwfNF)w!%` z*EFZi&P>-dlSYi0s7uwGI}B7&Qe9Ic#=%fuZ#?f^R**5%T~i}QFN||Y8JD$F{j%w< zsSzUui@U5b^;^cmEHkfjFxS+Gk&5XqYs~n~KcHltdUm3q10%*j#$-YWTZnt(chddP z(<+2dn}%B%VOpN=)tS#S08;m9>V3hK7cQhK7cQhK7cQhK7cQ aME(mmN68JDm^x+v00002*1j(Fh4CN^Z+Nx6W#! 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 literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$SHARP_LEFT$.png b/app/src/main/assets/new_models/$SHARP_LEFT$.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e6bbb1a08d197964fc3057b916062255f4ca4b GIT binary patch literal 1240 zcmV;}1Sk86P);Z+3yn6L|z74h)PI2#T?|mL?-+lfc zxU;j@`mggl`@h%T=UfOOgb+dqA%qY@2qAqC`1!)$ zVc_eO(z$F!wwby_y-D4n9#K2auA?4Ox2UVsrMc^G1$CjiN&QHjm?MDMoKinlABj+U zpkA%MtNv9Zg#Vr?$JBl5+T81!chuGDS3QO>lSArSb>y$TrKtC+KMWvaijbr`R zG^xIzF0L`>O7&>Tc^)0ax*NwKwWb;7yweLV?m1vaOY zrfN=q4meu!wU<>Lyw)cq7j+%*3b3N$p=W{DfbA)z^F5T%0Zx~E?O4^pYloqZ0gL$e z4N(V}=;4z$*L>r^F6ssG7VvbR>ayhPD&J674#Q$UejD&OupH>#kxT*y)DM9DDW$T7 z|KFS&ft|q0iie&AUIe!Gct$jndX@TxdVZD*S4aI$y}eKK4Sm-%M=fI(H;HAuUUmFB z7w~(4o98$-QCwUfw#RS4`qY}r_W11TgmHbzahFm2?4_2>yQVDaT)@jduU|mTt#bo* zO<6QC9LUyh^cMu40m6+dD5?Q@2Khq236*LA@Y$16$^M z5Rkb|U1&}BQ?#aQD;|CVcn)}?4M9NuGh;nPi@B!aanr5orM3hC8N=vmO?86U4LsAP zARt4ViqO{0&WvbHB@8@_Xien}vP~r*T2lpsJTuk+ zcL7&cJZ_{~Q@25ev8={1BiEX`HRcgIBifp}H6@IZZB5;BKPZF|Z%y5Dhj9$p25cMk zARup>Is?26?1&%=InRtez?;AoTKR{EQv8(kWJ>8wzYEJHXBc+?pY?G3Dd0=>os`li zeX1#|oMBXbJTjBjz#8>|l+w3-7%!`)Y;Ak79N3V%h<<287z?R)x8FEz2qV#sb+ls< zZ4qHKNE^a95B#0Gh<<287{`Ina~IJMxt~q-;w*54;*rYU%(e7IoiMfoZ}+*5Iyw}0 z;XkF6I=PGKhst53l#WvVAJanxZMbH%MugEI5k`YV7!49(G)RQeAQ47`L>LVcVKhjD z(IE5rL17M4z<$cTZ~F#ZO9&x^5JCtcgb+dqee(|vGUF(p&S1I#0000z9|8>y;bpKhp88yV>WRp=I1=9MH?=;jqGLkxkLMfuL^+7WFhI$72aI=A0Z9t+{{zaLoK$}74+Zoz`RicPN?Xl4Z zS&rlwh)=7srqa#TZ&p)p$zWAXtB17au{ zNeRneTZ^J2A}rdu)-k_6uv9c`lP%LehUx?6i!Z)ViQc?U(xD+V!FC4o?*pC&C%@d} zPq5y>IOlq4eb*X(CDlXD50ncee%y)|`5|zJf0~$Ql6Z65p6G*l1p(0 zv@q=b_c!uWzscLiCFa0){{jga=B(c_8`yLh_nG-O>ZZIs_29JW zksDl7=Ip$+-eMo)JJ#%jMGKyMQ2W60gGGjQ-?F7&Y>#RkeBk=1`he-m-<!wqyoL**adwzXGTkZAksqaj6RX*olyYP9UlNfWziJ%*|*}^JKEcqh)1J56q zd#bkUl6Y*-_Qtahv^Mbc_->Bu@4uh4d%9V4{Dj9{;&(4y@OzNt^{8q6q+sdg>m1i? zdU5>hgX{%Me@UI#HB# z{j#Q~p_Zc+XXMrI4eGgncc^Q-sh+S%dHdkU3U$}lAL@DUyo_9D{(Z?&0qxKevy#8( zKF~gqI;C>*%|hGTFQ)C0NZRl#sD94f=LZz$e%^5U%0nXlhI2I)TD z$AvEc?b@ZtrtRny9yzzmVBMMsU^v`TX-np_zAdKfrrIGFpqXOJ&G#xsM>~#3Fuql1 z?UXpiS-OEbtFMZzR@rN^+?=m;V(Sy;D&Y@a9~dkiPwSQ7SUCNd97|PWPAa$BV%Kh+ zBMuyU4VI~whHnv2th$&H?s#1JzDMn;36rnoLS=N^yi_j^Ac@AvcZdjA2>*P$&jn=H*8%>e+g zq(@SiOWgVIqD+@=F}Y2>1cWGp&PFYb1eGEK0OUNK63))5n5;~cai|W`s`&l@|A5WR zu}!lse)i^GME|0#eqHjjP8J0P1$E6Y2$2ORikfvKw0Qw1;mgx`yYbYQ_>Kit?OS}w zUNA7P(U4)ty{6@U$Q12M?J4`aTXOrmF#EO;(O=@K-NV6edL-A5-c9i+FJcZg zfoL#>^Z>Kc!}$7*Y#vx5M_;d9K8#p!&nkA|g;5G4kO7WhCE^JRXQ%8q`FB-`!paEe zsbz0FEk_sE%ChW&PU;d*9y}A6?+pu$H&pB4X%uisO7_7IO3R>9U3RNZLu#}tEk{dl zLPNS{pUgGFOo}ILDmjHvhTH&bU!}Wf$7h&mOq|%_r0%dk5dT|gE7z^tom>QUp`8eoYn&;O%=3|im@dEQ!EOZ<4C=OKr zdaRYM5X((fUn@J7KP!xl=FvLij2+e%26x*l zvI-Zas#-S*naitd;9*U<->V6O57|=HJB?10ogHVmtLRhNM* zI@l{dB~;FjZsmgAIDHId`cPzF>vyRoDwr$t@$3}~48t+I>fE~`HD++gaR84ehYTWI z4=6VJ#^P-C7g9FnNZ0w4>MS1SkM0@CWewf7TD*V5I^vc+k1Vti9j(ROR8%-agMO6* z%UYe@Kf1i^uZoBKBmFb5ZPd;tH(SM;)cxuDsc>TyEmZF=L=AZ2+mYkDNSCm0wBt8O z1k%s$HQksDcGwy$cv?ry?-dTA)*tqWIMVdZ?1}+ik)|(lAx(g8+%Y^!iX~@gLyGi4 zhsqjG%cb^e7yKfRGg?>rL9Dfvo{r;rzub4?epFwHpXUhBPEN{!U3!VTxZLC#wKH|+ z`Lu>wG;Sgz+2b=P)ZhI0xIXcM(eZ=DsR27ap$%2{UEd1&TH ze^N&KG%Vce_`x&J_yb!Xke>7;{&M5Y`J}n&0piJL{DkS`o|a~x)j!`U;#lK~n(sV^ z#RMgh&4Pxzi``dNll-i92pFX8@*He6a~%H%YAQ`Y;L_e)$}!ZXel@gbHC4^Dz}okR zOlR86uZR?v{QmLVnR!_P{}H{gH+)@Hu^gmTro2D;XXcv^U%1li6$kG4+2HR*$~;|N z{!d^pM1`Rm;iAu5x^O&E$WHYq;r^%Jij{L_t0#zax*e}8mx=+PQ)4J~5xjzb05p}# A`2YX_ literal 0 HcmV?d00001 diff --git a/app/src/main/assets/new_models/$SLIGHT_RIGHT$.png b/app/src/main/assets/new_models/$SLIGHT_RIGHT$.png new file mode 100644 index 0000000000000000000000000000000000000000..d5083f0f289c38de8855cfee9ca0cb1d1d31ce15 GIT binary patch literal 2326 zcmZuzc{mhY7ay`rV?3EcBh*+U%p!_m#Eg9@4YG&9*q6+NY_CC#jG`IEkSvWYRF;G+ zVIqdg-YDz)eU_BxEzv^0QN4ZN_dM@?o_o)^=lss^ch3FmrrVx269pXt0RR9|3v**U z&wB4}pb+o8rq`asGkhex85U4GB(u!(odfKh$WAuaXz#EPxR*~D!51DK63#;b0Q%8r zo*Uvz_JT!+1c#E)(HQw32sF>%4I|`XKOp2FjJ%VLEesbH;S1A-Yr&E71|S#=rXS%$ zMB|N3f0grY7Liy`nWjNeVwn z{^l|EC3!~#gp&ipLSehSUWBlVWQ@H0uF&uGvrlpW@xMx;q+et421M*;5GXhj@td1h zs=pgWpNRKxr$}&GwGvGxpo@i+?3Ps113k*-pHzN zoqPGscUC5xe9hWl7<>2gm!c2C_2MYliWWLbXj13`OTTSY&r)y7-#d^$JDCwLm^&$X z%#CJE{kAl#g|tY?QK6_Z#< zwiCKM?(Swc2wBKvb{X7w%l16gUh2!LE<53Rez+Y!64W_L^%uxrZy;hh#dVQbEpGNw zRFWX0(x*Hp(x$9T$Ox^RZuEsj!PDE9mWeqm^%SV04!u(Kj7t@?37?k&ymcsW%2oBP zCeSh@Kd?pmofe*MYHFRoGrxoWToS9sj_whdsA8XNZr(#{{Ca;7qw(TK;$<<1!2Xi& z=j}#jdN%c=0p^T$r|Zziv`w*p>CH~``72S|VJ#)q5NuoW=uA-HFm6L-``az=8FdS= ziA86t&SL>Za}Mxqe~T0c;UczTWn-hZJb~yLceIkky(CiZEs&2=A$PLtYSRqU>A|D) z0_M{5Kb}$6ZH?pz74GQ!`Q5FvC*93*2~L1iIsE*3Fk@o%eZY%>q}uDFjJ04dLIqyn zh#py+nNOZY(Oq7Z*d&sl_`IwI* zXp}0(WyHz67Pp@bKN^y`9zRZw1|D!^QHxg~K6=8e%t;1oyM~=r?I9Z35G;U68L@=P z;cRA#gVv|d6vW@wZWO80LXE;?x6_l+ZPGn=st^3-0ebZ&0e2VkU<~$e3<Ge0%wQmVMVT^wKT zP&7q8c=N)D&zx$}3H)kzViz-STWogXB})?(?b0ZL;>VWfmM_Ha1;z(-TwX(SE!?eC zG*+Ixq|a>4R=nSyRk$yu=BhqGdv@;4&)etYAXxtgdBHu= zs2mm63Z<{NQrL22BeNmr@%4R!6Ag~c_|t<2lXPWWUeKyW7Qd9lBprcU0v)W~JxF4f zjs3&+rH*8KM8}|EciSz|k4AmTrCKF}9a;J_wKe_k9pR?qA8+d>2s24_28DaIBCyto zcb|Y;e$;yHBL@hEh2t{)A8X3el3(8jVOOOK41gCJmb|ev8Whspl&)B#MofNYv+3#{ zXkSzLw!$`zL(Oi}(=y>qX~BtxRo8jvH3KT;9Fu+W+~7fh{hv_@dVAsr zTb#vlYOkJ3KD$KW#9#5Kv15Dw2fuSI_ zS!#wCl@C|^xi1_AMtQ1;ACZEm$_arl&ntAZkv)mUwsAg>ps7%#xMg1l(E(DMAoA%j y@QYx~#}0@+ = ArrayList() + for (bt in pairedDevices) listOfPairDevices.add(bt.name) + } + + private fun initClickListeners() { + startService.setOnClickListener { + startService() + serviceStarted = true + Snackbar.make(it, "Started Service", Snackbar.LENGTH_SHORT).show() + } + + stopService.setOnClickListener { + stopService() + serviceStarted = false + Snackbar.make(it, "Stopped Service", Snackbar.LENGTH_SHORT).show() + } + + connectBtn.setOnClickListener { + if (!serviceStarted) { + Snackbar.make(it, "Start Service First!", Snackbar.LENGTH_LONG).show() + } else { + val intent = Intent(MainNotificationService.CONNECT_BT) + sendBroadcast(intent) + Snackbar.make(it, "Connecting to TVS", Snackbar.LENGTH_SHORT).show() + } + } + + startNavigation.setOnClickListener { + if (!serviceStarted) { + Snackbar.make(it, "Start Service First!", Snackbar.LENGTH_LONG).show() + } else { + val intent = Intent(MainNotificationService.START_NAV) + sendBroadcast(intent) + Snackbar.make(it, "Started Navigation", Snackbar.LENGTH_SHORT).show() + } + } + + stopNavigation.setOnClickListener { + if (!serviceStarted) { + Snackbar.make(it, "Start Service First!", Snackbar.LENGTH_LONG).show() + } else { + val intent = Intent(MainNotificationService.STOP_NAV) + sendBroadcast(intent) + Snackbar.make(it, "Stopped Navigation", Snackbar.LENGTH_SHORT).show() + } + } + } + + private fun startService() { + val serviceIntent = Intent(this, MainNotificationService::class.java) + ContextCompat.startForegroundService(this, serviceIntent) + } + + private fun stopService() { + val serviceIntent = Intent(this, MainNotificationService::class.java) + stopService(serviceIntent) + finishAndRemoveTask() + } + + override fun onDestroy() { + super.onDestroy() + stopService() + } +} \ No newline at end of file diff --git a/app/src/main/java/sharan/experiments/myapplication/TVSHandler.kt b/app/src/main/java/sharan/experiments/myapplication/TVSHandler.kt new file mode 100644 index 0000000..382dcf7 --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/TVSHandler.kt @@ -0,0 +1,225 @@ +package sharan.experiments.myapplication + +import android.telephony.SmsManager +import android.util.Log +import com.welie.blessed.BluetoothBytesParser +import me.trevi.navparser.lib.DistanceUnit +import me.trevi.navparser.lib.NavigationData +import sharan.experiments.myapplication.utils.BluetoothHandler +import java.util.* + + +class TVSHandler(private var bluetoothHandler: BluetoothHandler) { + private var encodedN = "4e" + private var encodedO = "4f" + private var encodedDollar = "24" + + private var navData: NavigationData? = null + private var direction = "" + private var pictogramId = 0 + private var nextDirectionDistance = 0.0 + private var nextDirectionUnit = DistanceUnit.M + + private var remainingDistance = 0.0 + private var remainingDistanceUnit = DistanceUnit.M + private var count = 0 + + private var navTimer = Timer() + private var callTimer = Timer() + private var aliveTimer = Timer() + + private var isNavigating = false + private var isIncomingCall = false + + var smsManager: SmsManager = SmsManager.getDefault() + + private fun getHexString(str: String): String { + var hex = "" + for (c in str) { + hex += "%02x".format(c.toInt()) + } + return hex + } + + private fun writeNavigationInstructionsToDevice(){ + if (nextDirectionUnit == DistanceUnit.M && nextDirectionDistance > 300 || nextDirectionUnit == DistanceUnit.KM) { + count ++ + } else { + count = 1 + } + + when (count) { + in 30..40 -> { + writeRemainingDistanceInstruction() + } + in 70..100 -> { + writeETAInstruction() + } + 101 -> { + count = 1 + } + else -> { + writeNextDirectionInstruction() + } + } + } + + private fun writeRemainingDistanceInstruction() { + val message = getHexString("REM. DIST.") + val multiLine = "01" + val distanceHex = getDistanceHex(remainingDistance) + val unitHex = getUnitHex(remainingDistanceUnit) + val pictogramHex = getPictogramHex(8) + val instruction = "${encodedN}${distanceHex}${unitHex}${pictogramHex}${multiLine}${message}${encodedDollar}" + + Log.d("plaintext", "REM. DIST. $remainingDistance $remainingDistanceUnit") + Log.d("instructions", instruction) + bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes(instruction)) + } + + private fun writeETAInstruction() { + val eta = navData!!.eta.localeString + val message = getHexString("ETA. $eta") + val multiLine = "01" + val distanceHex = getDistanceHex(0.0) + val unitHex = getUnitHex(DistanceUnit.M) + val pictogramHex = getPictogramHex(99) + val instruction = "${encodedN}${distanceHex}${unitHex}${pictogramHex}${multiLine}${message}${encodedDollar}" + + Log.d("plaintext", "REM. DIST. $remainingDistance $remainingDistanceUnit") + Log.d("instructions", instruction) + bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes(instruction)) + } + + private fun writeNextDirectionInstruction() { + // do direction processing + var multiLine = "01" + + var direction1 = direction + var direction2 = "" + + if (direction.contains(':')) { + // two instructions - send two BT requests + val instructions = direction.split(':') + direction1 = instructions[0] + direction2 = instructions[1] + multiLine = "02" + } + + val unitHex = getUnitHex(nextDirectionUnit) + val distanceHex = getDistanceHex(nextDirectionDistance) + val pictogramHex = getPictogramHex(pictogramId) + + // send first instruction + val encodedMessage1 = getHexString(direction1) + val instruction1 = "${encodedN}${distanceHex}${unitHex}${pictogramHex}${multiLine}${encodedMessage1}${encodedDollar}" + Log.d("plaintext1", "$direction1 $nextDirectionDistance $nextDirectionUnit") + Log.d("instructions1", instruction1) + bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes(instruction1)) + + if (multiLine == "02") { + val encodedMessage2 = getHexString(direction2) + val instruction2 = "${encodedO}${encodedMessage2}${encodedDollar}" + Thread.sleep(100) + bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes(instruction2)) + Log.d("plaintext2", direction2) + Log.d("instructions2", instruction2) + + } + } + + private fun getPictogramHex(id: Int) = "%02x".format(id) + + private fun getDistanceHex(distance: Double) = "%04x".format((distance * 10).toInt()) + + private fun getUnitHex(unit: DistanceUnit): String { + return if (unit == DistanceUnit.M) { + "00" // Meters + } else { + "01" // Kilometers + } + } + + fun updateValues( + direction: String, + distance: Double, + distanceUnit: DistanceUnit, + pictogramId: Int, + remainingDistance: Double, + remainingDistanceUnit: DistanceUnit, + navData: NavigationData + ) { + this.direction = direction + this.nextDirectionDistance = distance + this.nextDirectionUnit = distanceUnit + this.pictogramId = pictogramId + this.remainingDistance = remainingDistance + this.remainingDistanceUnit = remainingDistanceUnit + this.navData = navData + } + + fun keepConnectionAlive() { + aliveTimer = Timer() + aliveTimer.schedule(object : TimerTask() { + override fun run() { + if (!isNavigating && !isIncomingCall) bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes("4c5b")) + } + }, 0, 400) + } + + fun stopConnectionAlive() { + aliveTimer.cancel() + } + + fun updateAsRerouting() { + nextDirectionDistance = 0.0 + nextDirectionUnit = DistanceUnit.M + pictogramId = 99 + direction = "REROUTING" + } + + fun startNavigation() { + isNavigating = true + navTimer = Timer() + navTimer.schedule(object : TimerTask() { + override fun run() { + if (!isIncomingCall) writeNavigationInstructionsToDevice() + } + }, 0, 400) + } + + fun stopNavigation() { + isNavigating = false + navTimer.cancel() + } + + fun startShowingIncomingCallMessage(callerName: String) { + isIncomingCall = true + val incomingCallDetails = getHexString("C${if (callerName.length > 18) callerName.substring(0, 18) else callerName}$") + callTimer = Timer() + callTimer.schedule(object : TimerTask() { + override fun run() { + Log.d("incomingCallHandler", callerName) + bluetoothHandler.writeToTVS(BluetoothBytesParser.string2bytes(incomingCallDetails)) + Thread.sleep(100) + } + },0, 400) + } + + fun stopShowingIncomingCallMessage(phoneNumber: String, isContact: Boolean) { + isIncomingCall = false + callTimer.cancel() + + if (phoneNumber.isEmpty()) return + + var smsText = "Thanks for calling, currently I am driving. Will call you after sometime.\n\n - Automatic reply from TVS Apache" + if (isNavigating && navData != null && navData!!.isValid() && isContact) { + val eta = navData!!.eta.localeString + val destination = navData!!.finalDirection + val currentLocation = navData!!.nextDirection.localeString + smsText = "Currently I am driving. Will call you after sometime.\n\nIf you are expecting me, currently at $currentLocation. $eta for $destination" + } + Log.d("SMS", "Sending SMS $smsText") + smsManager.sendTextMessage(phoneNumber, null, smsText, null, null) + } +} \ No newline at end of file diff --git a/app/src/main/java/sharan/experiments/myapplication/services/GoogleNavigationListener.kt b/app/src/main/java/sharan/experiments/myapplication/services/GoogleNavigationListener.kt new file mode 100644 index 0000000..ad992a7 --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/services/GoogleNavigationListener.kt @@ -0,0 +1,20 @@ +package sharan.experiments.myapplication.services + +import android.content.Intent +import me.trevi.navparser.lib.NavigationNotification +import me.trevi.navparser.service.NAVIGATION_DATA +import me.trevi.navparser.service.NavigationListener + +class GoogleNavigationListener : NavigationListener() { + override fun onCreate() { + enabled = true + super.onCreate() + } + + override fun onNavigationNotificationUpdated(navNotification: NavigationNotification) { + val intent = Intent(MainNotificationService.NAVDATA_UPDATED) + intent.putExtra(NAVIGATION_DATA, navNotification.navigationData) + sendBroadcast(intent) + super.onNavigationNotificationUpdated(navNotification) + } +} \ No newline at end of file diff --git a/app/src/main/java/sharan/experiments/myapplication/services/MainNotificationService.kt b/app/src/main/java/sharan/experiments/myapplication/services/MainNotificationService.kt new file mode 100644 index 0000000..baeb9bc --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/services/MainNotificationService.kt @@ -0,0 +1,220 @@ +package sharan.experiments.myapplication.services + +import android.R +import android.app.Notification +import android.app.PendingIntent +import android.app.Service +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.database.Cursor +import android.net.Uri +import android.os.IBinder +import android.provider.ContactsContract +import android.telephony.PhoneStateListener +import android.telephony.TelephonyManager +import android.util.Log +import androidx.annotation.Nullable +import androidx.core.app.NotificationCompat +import me.trevi.navparser.lib.NavigationData +import me.trevi.navparser.service.NAVIGATION_DATA +import sharan.experiments.myapplication.App.Companion.CHANNEL_ID +import sharan.experiments.myapplication.MainActivity +import sharan.experiments.myapplication.TVSHandler +import sharan.experiments.myapplication.utils.BluetoothHandler +import sharan.experiments.myapplication.utils.Direction +import sharan.experiments.myapplication.utils.DirectionImageMapper + + +class MainNotificationService : Service() { + private val navigationServiceBroadcastReceiver = NavigationServiceBroadcastReceiver() + + private lateinit var phoneListener:PhoneListener + private var phoneListenerCount = 0 + + lateinit var directionImageMapper: DirectionImageMapper + lateinit var tvsHandler: TVSHandler + lateinit var bluetoothHandler: BluetoothHandler + + override fun onCreate() { + super.onCreate() + directionImageMapper = DirectionImageMapper(applicationContext) + bluetoothHandler = BluetoothHandler(applicationContext) + tvsHandler = TVSHandler(bluetoothHandler) + phoneListener = PhoneListener() + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + val notificationIntent = Intent(this, MainActivity::class.java) + val pendingIntent = PendingIntent.getActivity( + this, + 0, notificationIntent, 0 + ) + + val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID) + .setContentTitle("TVS Navigation Service") + .setContentText("Ready to start navigation") + .setSmallIcon(R.drawable.ic_dialog_info) + .setContentIntent(pendingIntent) + .build() + + startForeground(1, notification) + + val intentFilter = IntentFilter() + intentFilter.addAction(NAVDATA_UPDATED) + intentFilter.addAction(CONNECT_BT) + intentFilter.addAction(NAVDATA_REMOVED) + intentFilter.addAction(START_NAV) + intentFilter.addAction(STOP_NAV) + + registerReceiver(navigationServiceBroadcastReceiver, intentFilter) + + val tm = applicationContext.getSystemService(TELEPHONY_SERVICE) as TelephonyManager + tm.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE) + + return START_NOT_STICKY + } + + override fun onDestroy() { + unregisterReceiver(navigationServiceBroadcastReceiver) + tvsHandler.stopNavigation() + tvsHandler.stopConnectionAlive() + bluetoothHandler.cancelConnections() + super.onDestroy() + } + + private fun processNavigationData(navData: NavigationData) { + val isRerouting = navData.isRerouting + val direction = navData.actionIcon.bitmap?.let { directionImageMapper.getDirectionFromImage( + it + ) } + val distance = navData.nextDirection.navigationDistance?.distance + val unit = navData.nextDirection.navigationDistance?.unit + if (isRerouting) { + tvsHandler.updateAsRerouting() + } else if (direction != null && distance != null && unit != null) { + val pairPictogramDirection = Direction.getTVSPictogramAndDirection(direction) + Log.d("tvsData", "$pairPictogramDirection") + tvsHandler.updateValues( + pairPictogramDirection.second, + distance, + unit, + pairPictogramDirection.first, + navData.remainingDistance.distance, + navData.remainingDistance.unit, + navData + ) + } + } + + @Nullable + override fun onBind(intent: Intent?): IBinder? { + return null + } + + inner class NavigationServiceBroadcastReceiver : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent) { + when (intent.action) { + NAVDATA_UPDATED -> { + val navData = intent.getParcelableExtra(NAVIGATION_DATA) + Log.d(receiverTag, "got nav data: $navData") + if (navData != null) { + processNavigationData(navData) + } + } + + CONNECT_BT -> { + Log.d(receiverTag, "got connect BT request") + bluetoothHandler.connectToTVS() + tvsHandler.keepConnectionAlive() + } + + START_NAV -> { + tvsHandler.startNavigation() + } + + STOP_NAV -> { + tvsHandler.stopNavigation() + } + } + + } + } + + private fun getContactName(phoneNumber: String?, context: Context): String? { + if (phoneNumber.isNullOrEmpty()) return "" + + val uri: Uri = Uri.withAppendedPath( + ContactsContract.PhoneLookup.CONTENT_FILTER_URI, + Uri.encode(phoneNumber) + ) + + val projection = arrayOf(ContactsContract.PhoneLookup.DISPLAY_NAME) + var contactName = "" + val cursor: Cursor? = context.contentResolver.query(uri, projection, null, null, null) + if (cursor != null) { + if (cursor.moveToFirst()) { + contactName = cursor.getString(0) + } + cursor.close() + } + return contactName + } + + inner class PhoneListener: PhoneStateListener() { + private var tag: String = javaClass.name + private var isContact = true + override fun onCallStateChanged(state: Int, phoneNumber: String?) { + super.onCallStateChanged(state, phoneNumber) + if (phoneNumber.isNullOrEmpty()) return + + var callerName = getContactName(phoneNumber, applicationContext) + var myPhoneNumber = phoneNumber + + if (phoneNumber.startsWith("+91") && phoneNumber.length > 10) { + myPhoneNumber = phoneNumber.substring(3); // reduce number to 10 characters if extension exists + } + + if (callerName.isNullOrEmpty()) { + isContact = false + callerName = myPhoneNumber + } else { + isContact = true + } + + when (state) { + TelephonyManager.CALL_STATE_IDLE -> { + phoneListenerCount++ + if (phoneListenerCount >= 1) { + phoneListenerCount = 0 + // Send SMS for missed call. + tvsHandler.stopShowingIncomingCallMessage(phoneNumber, isContact) + } + } + TelephonyManager.CALL_STATE_OFFHOOK -> { + phoneListenerCount = -1 + tvsHandler.stopShowingIncomingCallMessage("", isContact) + } + TelephonyManager.CALL_STATE_RINGING -> { + phoneListenerCount++ + if (phoneListenerCount >= 1) { + phoneListenerCount = 0 + // Send signal for showing incoming message. + Log.d(tag, "Incoming call - Name: $callerName, Number: $myPhoneNumber") + tvsHandler.startShowingIncomingCallMessage(callerName) + } + } + } + } + } + + companion object { + const val receiverTag = "NavigationServiceBroadcastReceiver" + const val NAVDATA_UPDATED = "NAVDATA_UPDATED" + const val CONNECT_BT = "CONNECT_BT" + const val NAVDATA_REMOVED = "NAVDATA_REMOVED" + const val START_NAV = "START_NAV" + const val STOP_NAV = "STOP_NAV" + } +} diff --git a/app/src/main/java/sharan/experiments/myapplication/utils/BluetoothHandler.kt b/app/src/main/java/sharan/experiments/myapplication/utils/BluetoothHandler.kt new file mode 100644 index 0000000..0927a64 --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/utils/BluetoothHandler.kt @@ -0,0 +1,137 @@ +package sharan.experiments.myapplication.utils + +import android.bluetooth.BluetoothGattCharacteristic +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.widget.Toast +import com.welie.blessed.* +import java.util.* + + +class BluetoothHandler(context: Context) { + private var centralManager: BluetoothCentralManager + private val TVS_SERVICE_UUID: UUID = UUID.fromString("00005500-d102-11e1-9b23-000240198212") + private val TVS_WRITE_CHARACTERISTIC_UUID: UUID = UUID.fromString("00005502-d102-11e1-9b23-000240198212") + + private lateinit var tvsPeripheral: BluetoothPeripheral + private lateinit var tvsWriteCharacteristic: BluetoothGattCharacteristic + + private var isConnected = false + + private val bluetoothCentralManagerCallback: BluetoothCentralManagerCallback = + object : BluetoothCentralManagerCallback() { + override fun onConnectedPeripheral(peripheral: BluetoothPeripheral) { + super.onConnectedPeripheral(peripheral) + isConnected = true + Toast.makeText(context, "Connected to device, ${peripheral.name}", Toast.LENGTH_LONG).show() + getWriteCharacteristic() + initBTConnection() + } + + override fun onDisconnectedPeripheral( + peripheral: BluetoothPeripheral, + status: HciStatus + ) { + super.onDisconnectedPeripheral(peripheral, status) + isConnected = false + } + } + + private val peripheralCallback: BluetoothPeripheralCallback = + object : BluetoothPeripheralCallback() { + override fun onCharacteristicWrite( + peripheral: BluetoothPeripheral, + value: ByteArray, + characteristic: BluetoothGattCharacteristic, + status: GattStatus + ) { + Log.d("tag", "Write successful ${value.decodeToString()}") + } + + } + + init { + centralManager = BluetoothCentralManager( + context, bluetoothCentralManagerCallback, Handler(Looper.getMainLooper()) + ) + tvsPeripheral = centralManager.getPeripheral("CC:88:26:18:42:92") + } + + private fun getWriteCharacteristic() { + tvsWriteCharacteristic = + tvsPeripheral.getCharacteristic(TVS_SERVICE_UUID, TVS_WRITE_CHARACTERISTIC_UUID)!! + } + + fun connectToTVS() { + centralManager.connectPeripheral(tvsPeripheral, peripheralCallback) + initBTConnection() + } + + private fun initBTConnection() { + if (isConnected) { + tvsPeripheral.writeCharacteristic(tvsWriteCharacteristic, BluetoothBytesParser.string2bytes("0100"), WriteType.WITH_RESPONSE) // request write + Thread.sleep(1000) + writeToTVS(BluetoothBytesParser.string2bytes("564170616368652052545224")) // bike name + writeToTVS(BluetoothBytesParser.string2bytes("580004000201")) // missed calls + Thread.sleep(400) + writeToTVS(BluetoothBytesParser.string2bytes("580004000201")) // missed calls + Thread.sleep(400) + writeToTVS(BluetoothBytesParser.string2bytes("580004000201")) // missed calls + Thread.sleep(400) + writeToTVS(BluetoothBytesParser.string2bytes("5711")) // random stuff I found in code/log + sendHourMinute() + sendHourMinute() + writeToTVS(BluetoothBytesParser.string2bytes(getHexString("MTVS Rider$"))) // rider-name + sendHourMinute() + writeToTVS(BluetoothBytesParser.string2bytes(getHexString("MTVS Rider$"))) // rider-name + } + } + + private fun sendHourMinute() { + var i: Int + val instance = Calendar.getInstance() + var i2 = instance[Calendar.HOUR_OF_DAY] // Hour/24h format + + val i3 = instance[Calendar.MINUTE] // Minute + if (i2 == 0) { + i2 += 12 // convert to 12h time + } else { + if (i2 != 12) { + if (i2 > 12) { + i2 -= 12 // convert to 12h time + } + } + i = 1 + val bArr = byteArrayOf(java.lang.Byte.decode(getHexString("H")).toByte(), i2.toByte(), i3.toByte(), i.toByte()) + writeToTVS(bArr) + Thread.sleep(100) + } + i = 0 + val bArr2 = byteArrayOf(java.lang.Byte.decode(getHexString("H")).toByte(), i2.toByte(), i3.toByte(), i.toByte()) + writeToTVS(bArr2) + Thread.sleep(100) + } + + private fun getHexString(str: String): String { + var hex = "" + for (c in str) { + hex += "%02x".format(c.toInt()) + } + return hex + } + + fun writeToTVS(byteArray: ByteArray) { + if (!isConnected) connectToTVS() + if (isConnected) { + Log.d("tag", "writeToTVS - ${byteArray.decodeToString()}") + tvsPeripheral.writeCharacteristic(tvsWriteCharacteristic, byteArray, WriteType.WITHOUT_RESPONSE) + } + } + + fun cancelConnections() { + centralManager.cancelConnection(tvsPeripheral) + } + +} \ No newline at end of file diff --git a/app/src/main/java/sharan/experiments/myapplication/utils/Direction.kt b/app/src/main/java/sharan/experiments/myapplication/utils/Direction.kt new file mode 100644 index 0000000..e249d8b --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/utils/Direction.kt @@ -0,0 +1,35 @@ +package sharan.experiments.myapplication.utils + +class Direction { + companion object { + fun getTVSPictogramAndDirection(gMapsDirection: String): Pair { + return when (gMapsDirection) { + "ARRIVE" -> Pair(8, "DESTINATION") + "ARRIVE_LEFT" -> Pair(8, "DESTINATION:LEFT") + "ARRIVE_RIGHT" -> Pair(8, "DESTINATION:RIGHT") + "ARRIVE_STRAIGHT" -> Pair(8, "DESTINATION:STRAIGHT") + "CONTINUE_STRAIGHT" -> Pair(7, "CONTINUE:STRAIGHT") + "CONTINUE_LEFT" -> Pair(22, "CONTINUE:LEFT") + "CONTINUE_RETURN" -> Pair(6, "MAKE A:U TURN") + "CONTINUE_RIGHT" -> Pair(24, "CONTINUE:RIGHT") + "CONTINUE_SLIGHT_LEFT", "SLIGHT_LEFT" -> Pair(2, "SLIGHT LEFT") + "CONTINUE_SLIGHT_RIGHT", "SLIGHT_RIGHT" -> Pair(5, "SLIGHT RIGHT") + "DEPART" -> Pair(7, "DEPART") + "FORK" -> Pair(7, "FORK") + "ROTATORY_EXIT", "ROTATORY_EXIT_INVERTED", "ROTATORY_STRAIGHT", "ROTATORY_STRAIGHT_INVERTED" -> Pair(68, "ROUNDABOUT: EXIT STRAIGHT") + "ROTATORY_LEFT", "ROTATORY_LEFT_INVERTED" -> Pair(66, "ROUNDABOUT: EXIT LEFT") + "ROTATORY_RIGHT", "ROTATORY_RIGHT_INVERTED" -> Pair(70, "ROUNDABOUT: EXIT RIGHT") + "ROTATORY_SHARP_LEFT", "ROTATORY_SHARP_LEFT_INVERTED" -> Pair(65, "ROUNDABOUT: EXIT SHARP-LEFT") + "ROTATORY_SHARP_RIGHT", "ROTATORY_SHARP_RIGHT_INVERTED" -> Pair(71, "ROUNDABOUT: EXIT SHARP-LEFT") + "ROTATORY_SLIGHT_LEFT", "ROTATORY_SLIGHT_LEFT_INVERTED" -> Pair(67, "ROUNDABOUT: EXIT SLIGHT-LEFT") + "ROTATORY_SLIGHT_RIGHT", "ROTATORY_SLIGHT_RIGHT_INVERTED" -> Pair(69, "ROUNDABOUT: EXIT SLIGHT-RIGHT") + "ROTATORY_TOTAL", "ROTATORY_TOTAL_INVERTED" -> Pair(6, "ROUNDABOUT: EXIT TOTAL") + "SHARP_LEFT" -> Pair(1, "SHARP:LEFT TURN") + "SHARP_RIGHT" -> Pair(4, "SHARP:RIGHT TURN") + else -> { + Pair(8, "UNKNOWN") + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/sharan/experiments/myapplication/utils/DirectionImageMapper.kt b/app/src/main/java/sharan/experiments/myapplication/utils/DirectionImageMapper.kt new file mode 100644 index 0000000..5daf24b --- /dev/null +++ b/app/src/main/java/sharan/experiments/myapplication/utils/DirectionImageMapper.kt @@ -0,0 +1,98 @@ +package sharan.experiments.myapplication.utils + +import android.content.Context +import android.content.res.AssetManager +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.util.Log +import org.jetbrains.annotations.NotNull +import java.io.File +import java.io.IOException +import java.io.InputStream +import kotlin.jvm.internal.Intrinsics + + +class DirectionImageMapper(private val context: Context) { + private val newModels: MutableMap = LinkedHashMap() + + init { + loadModelsFromAssets() + } + + private fun loadModelsFromAssets() { + val assetManager: AssetManager = context.assets + val newModelsDir = "new_models" + val newModelsList = assetManager.list(newModelsDir) + + if (newModelsList != null) { + for (model in newModelsList) { + val modelName = toModelName(model) + + val modelPath = newModelsDir + File.separator + model + val bitmap = getBitmapFromAsset(modelPath) + + if (bitmap != null) { + newModels[modelName] = bitmap + } + } + } + } + + private fun toModelName(modelName: String): String { + return modelName.substring(1, modelName.lastIndexOf('$')) + } + + private fun getBitmapFromAsset(str: String): Bitmap? { + val bitmap: Bitmap? = try { + val open: InputStream = context.assets.open(str) + BitmapFactory.decodeStream(open) + } catch (e: IOException) { + e.printStackTrace() + null + } + if (bitmap == null) { + Intrinsics.throwNpe() + } + return bitmap + } + + private fun compareBitmaps(bitmap: Bitmap, bitmap2: Bitmap): Float { + val iArr = IntArray(14400) + val iArr2 = IntArray(14400) + bitmap.getPixels(iArr, 0, 120, 0, 0, 120, 120) + bitmap2.getPixels(iArr2, 0, 120, 0, 0, 120, 120) + var i = 0 + for (i2 in 0..14399) { + if (iArr[i2] != iArr2[i2]) { + i++ + } + } + return i.toFloat() / 14400.toFloat() * 100.toFloat() + } + + private fun resizeToDefaultSize(bitmap: Bitmap): Bitmap { + return Bitmap.createScaledBitmap(bitmap, 120, 120, false) + } + + fun getDirectionFromImage(@NotNull bitmap: Bitmap): String { + val resizeToDefaultSize: Bitmap = resizeToDefaultSize(bitmap) + var num: Int? = null + var str: String? = null + + for ((key, value) in this.newModels.entries) { + val compareBitmaps2 = compareBitmaps(resizeToDefaultSize, resizeToDefaultSize(value)) + if (num == null || compareBitmaps2.compareTo(num.toInt().toFloat()) < 0) { + num = Integer.valueOf(compareBitmaps2.toInt()) + str = key + } + } + Log.d("DIRECTION_RESULT", "$str $num") + if (str != null) { + if (num!!.toInt().toDouble() <= 35.0) { + return str + } + } + return "UNKNOWN" + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..cc14f03 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..a4f78de --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..0d14bcb --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,57 @@ + + + + +