From 0da5449c5cbfec79490912b126e860341ecfb616 Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:09:01 +0900 Subject: [PATCH 1/8] Remove the unused okHttpCallFactory provider Nothing injects Call.Factory: Retrofit gets the OkHttpClient from provideOkHttp. The unused client also logged full bodies, unredacted, in debug builds. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- .../di/modules/NetModule.kt | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/di/modules/NetModule.kt b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/di/modules/NetModule.kt index f486a0b..7c93533 100644 --- a/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/di/modules/NetModule.kt +++ b/app/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/di/modules/NetModule.kt @@ -1,6 +1,5 @@ package com.nativeapptemplate.nativeapptemplatefree.di.modules -import androidx.tracing.trace import com.nativeapptemplate.nativeapptemplatefree.BuildConfig import com.nativeapptemplate.nativeapptemplatefree.NativeAppTemplateConstants import com.nativeapptemplate.nativeapptemplatefree.data.item_tag.ItemTagApi @@ -17,7 +16,6 @@ import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import kotlinx.serialization.json.Json -import okhttp3.Call import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -89,21 +87,6 @@ class NetModule { @Provides fun provideItemTagApi(retrofit: Retrofit): ItemTagApi = ItemTagApi.create(retrofit) - - @Provides - @Singleton - fun okHttpCallFactory(): Call.Factory = trace("NativeAppTemplateOkHttpClient") { - OkHttpClient.Builder() - .addInterceptor( - HttpLoggingInterceptor() - .apply { - if (BuildConfig.DEBUG) { - setLevel(HttpLoggingInterceptor.Level.BODY) - } - }, - ) - .build() - } } /** From 7559535455da581dde48b97d5d89bec7d81e821b Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:09:12 +0900 Subject: [PATCH 2/8] Remove model/proguard-rules.pro, which no build reads :model never minifies (false is also the library default) and does not list the file as a consumer ProGuard file, so its rules never reached R8. Its only line was also malformed: `-keep com...model.**` has no class specification keyword. The app's proguard-rules.pro is unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- model/build.gradle.kts | 7 ------- model/proguard-rules.pro | 1 - 2 files changed, 8 deletions(-) delete mode 100644 model/proguard-rules.pro diff --git a/model/build.gradle.kts b/model/build.gradle.kts index 479ec55..4e7234d 100644 --- a/model/build.gradle.kts +++ b/model/build.gradle.kts @@ -9,13 +9,6 @@ android { defaultConfig { minSdk = 26 - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } } kotlin { diff --git a/model/proguard-rules.pro b/model/proguard-rules.pro deleted file mode 100644 index 9b219a3..0000000 --- a/model/proguard-rules.pro +++ /dev/null @@ -1 +0,0 @@ --keep com.nativeapptemplate.nativeapptemplatefree.model.** \ No newline at end of file From 92ba00e469a644421aa5d599faa13784dbf83c6d Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:10:11 +0900 Subject: [PATCH 3/8] Remove the Hilt test modules no test installs TestDispatcher(s)Module, TestCryptoModule and TestDataStoreModule are @TestInstallIn/@InstallIn modules, but no test is a @HiltAndroidTest and the test source set has no Hilt annotation processor, so Hilt never builds a test component that would use them. The tests construct their dependencies directly (InMemoryDataStore stays: tests use it). With the modules gone nothing uses hilt-android-testing, so drop that dependency. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- app/build.gradle.kts | 1 - .../datastoreTest/TestCryptoModule.kt | 28 ------------ .../datastoreTest/TestDataStoreModule.kt | 40 ----------------- .../testing/di/TestDispatcherModule.kt | 33 -------------- .../testing/di/TestDispatchersModule.kt | 44 ------------------- gradle/libs.versions.toml | 1 - 6 files changed, 147 deletions(-) delete mode 100644 app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestCryptoModule.kt delete mode 100644 app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestDataStoreModule.kt delete mode 100644 app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatcherModule.kt delete mode 100644 app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatchersModule.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ae78527..1478f57 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -115,7 +115,6 @@ dependencies { testImplementation(platform(libs.androidx.compose.bom)) testImplementation(libs.androidx.compose.ui.test.junit4) testImplementation(libs.androidx.navigation.testing) - testImplementation(libs.hilt.android.testing) testImplementation(libs.kotlin.test) testImplementation(libs.kotlinx.coroutines.test) testImplementation(libs.robolectric) diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestCryptoModule.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestCryptoModule.kt deleted file mode 100644 index b89fd5d..0000000 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestCryptoModule.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.nativeapptemplate.nativeapptemplatefree.datastoreTest - -import com.google.crypto.tink.Aead -import com.google.crypto.tink.KeyTemplates -import com.google.crypto.tink.KeysetHandle -import com.google.crypto.tink.RegistryConfiguration -import com.google.crypto.tink.aead.AeadConfig -import com.nativeapptemplate.nativeapptemplatefree.di.modules.CryptoModule -import dagger.Module -import dagger.Provides -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn -import javax.inject.Singleton - -@Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [CryptoModule::class], -) -internal object TestCryptoModule { - @Provides - @Singleton - fun providesAead(): Aead { - AeadConfig.register() - val keysetHandle = KeysetHandle.generateNew(KeyTemplates.get("AES256_GCM")) - return keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead::class.java) - } -} diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestDataStoreModule.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestDataStoreModule.kt deleted file mode 100644 index d9ed0bb..0000000 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/datastoreTest/TestDataStoreModule.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.nativeapptemplate.nativeapptemplatefree.datastoreTest - -import androidx.datastore.core.DataStore -import com.nativeapptemplate.nativeapptemplatefree.UserPreferences -import com.nativeapptemplate.nativeapptemplatefree.datastore.UserPreferencesSerializer -import com.nativeapptemplate.nativeapptemplatefree.di.modules.DataStoreModule -import dagger.Module -import dagger.Provides -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn -import javax.inject.Singleton - -@Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [DataStoreModule::class], -) -internal object TestDataStoreModule { - @Provides - @Singleton - fun providesUserPreferencesDataStore( - serializer: UserPreferencesSerializer, - ): DataStore = InMemoryDataStore(serializer.defaultValue) -} diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatcherModule.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatcherModule.kt deleted file mode 100644 index faed07f..0000000 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatcherModule.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.nativeapptemplate.nativeapptemplatefree.testing.di - -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.test.TestDispatcher -import kotlinx.coroutines.test.UnconfinedTestDispatcher -import javax.inject.Singleton - -@Module -@InstallIn(SingletonComponent::class) -internal object TestDispatcherModule { - @Provides - @Singleton - fun providesTestDispatcher(): TestDispatcher = UnconfinedTestDispatcher() -} diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatchersModule.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatchersModule.kt deleted file mode 100644 index 32e0fe6..0000000 --- a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/testing/di/TestDispatchersModule.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.nativeapptemplate.nativeapptemplatefree.testing.di - -import com.nativeapptemplate.nativeapptemplatefree.di.modules.DispatchersModule -import com.nativeapptemplate.nativeapptemplatefree.network.Dispatcher -import com.nativeapptemplate.nativeapptemplatefree.network.NativeAppTemplateDispatchers -import dagger.Module -import dagger.Provides -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.test.TestDispatcher - -@Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [DispatchersModule::class], -) -internal object TestDispatchersModule { - @Provides - @Dispatcher(NativeAppTemplateDispatchers.IO) - fun providesIODispatcher(testDispatcher: TestDispatcher): CoroutineDispatcher = testDispatcher - - @Provides - @Dispatcher(NativeAppTemplateDispatchers.Default) - fun providesDefaultDispatcher( - testDispatcher: TestDispatcher, - ): CoroutineDispatcher = testDispatcher -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 55cf119..6336585 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,7 +51,6 @@ androidx-navigation-testing = { group = "androidx.navigation", name = "navigatio androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstaller" } androidx-tracing-ktx = { group = "androidx.tracing", name = "tracing-ktx", version.ref = "androidxTracing" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } -hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" } hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } junit = { group = "junit", name = "junit", version.ref = "junit4" } kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" } From 9167d981508b6142faf029e5645871cb3111da4a Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:10:21 +0900 Subject: [PATCH 4/8] Remove unused string, drawable and mipmap resources Nothing references these (Kotlin R.*, XML @string/@drawable/@mipmap, or getIdentifier, which the app never calls), and lint's UnusedResources check reports each of them: - strings instructions, open, role, unauthorized, cancel and shop_name_is_required, from values/ and values-ja/ together; - drawable ic_placeholder_default; - mipmap ic_launcher_round: the manifest sets no android:roundIcon. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- .../res/drawable/ic_placeholder_default.xml | 63 ------------------ .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 -- .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2402 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1568 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3396 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5458 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 7672 -> 0 bytes app/src/main/res/values-ja/strings.xml | 6 -- app/src/main/res/values/strings.xml | 6 -- 9 files changed, 81 deletions(-) delete mode 100644 app/src/main/res/drawable/ic_placeholder_default.xml delete mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/app/src/main/res/drawable/ic_placeholder_default.xml b/app/src/main/res/drawable/ic_placeholder_default.xml deleted file mode 100644 index 9fa327c..0000000 --- a/app/src/main/res/drawable/ic_placeholder_default.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 1084c24..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index 791c41cfe31284612210ec12801a3fe153991fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2402 zcmV-o37z&*Nk&Fm2><|BMM6+kP&iCZ2><{uN5Byf^#+2rZR7B#z3qn(5fk8CO)511 zL1jT!>e{xcjhpXJ(e^U0ZE5CnncEZS&-Uzk$~8zc-V=C>0f!SQSHFPD>|PrNT~p?U z8K=z5VZm)A$&r-)TlEgS_&R^__;gnH5$6zW`eZFrI*}4ev3Bc;X*>{~Ndr5oAf`=R_`XXwd-TjW4mY&jO8(*h{BZHh|c< zm~Jae0NngE8>da!Wa{oVHXEEAu({Xi4>mtvZ(92$n~k^GWSn{)K$3M+i3ikr=W3L~ zbb6G{4I7B%BAb!^V}MV(*1`b|rPC-kvUwB{ogkIv=Q()@1`!P@5Hx^P$>Zn_;J+SMl_d0!0a=OVIxKb*7FeSinF zD~ZjQ^xISTLSNW?{|C%lx@Ix48D|5+D}Q3mIT0>TXciOZt(;#=p3N~EIG0KnNYBYD zdMyPDOVC)hdcv?&f`e^j{mm6?B*tlFyNl#TF2&IoB{>{07uFCOFU%Xd%Cn`Zb2&{| zz8uA|&g}dzoz^Xrp{HQ#&=aH4u+1u!!?x+Djgb^7sgkNookB2y0k=&hBhbl zdsyJ&rPJdU=b5g!bkJ4f_YFH!-o=)2Inm~HHB#?}8LK%eSN^ntK&8hNWeC&4Y(6D5 zmzzJiy7BxgD*3FoB#=dmO^?;p)A0_qyvtCcdZ8NhQA(iFhSIli8EVj9G@$zrhh;<4 z8ftB;s3HfQ%t~${D|61AX3Z^3oLqv=qIVHxN^6Q$5SQ8oqaCoA6ho~eDuG(c5Lstl zn|iBQf*Ri-qEQXbFzW?TTSwNR@e&7{dr28^_umXVz^0jlnloHP#SgPy{BZ5DUJ8{3 z7Oo=o>7s-7>Qa_CEGzU!ttzfP%DhSs+vM-(BzMdXVLL1(b)VtjTKA;O0C-d%Vb%7P zO+F}p1)L6b+2G@5SPjk1SWO;yAVbh?Vl#@b|7w5^ciG%sAJ4iwXM5Oz_`?ASl*%yA z%V$#-sU*wrP)3tb^25Ka+85;TB4r%mY09~ zJN>#wHx|qvQ{8xZUVUWaZu7f8jMTcK7JKiLeF;0C6WgxX(##xEEj`!;_22!w2B0J1 z>S1i-q5XshQqa`IY)UOn<`Ct|tE6&M0zb7yJ<%leO}DypcUafFd0kB&KRla{kM5j^@3b)WGuX zw%No+PSV7D3grKK*A4-r_aOeU1msY6NN#q+`#*OMFmsWgRF<&vSncXRlr`@UJ8I*6 z$xUw$&F*d(L|8vGxFK z)iP%Zn42+>5KyW;6J>$Lb0IJJ>CpV1lDrSY8mR;(XJ&7@?;Shi^dv^!lMpaeO_9?n|>NpYUjL+XsXf>RoMC&tD(^Ewck`1Z+(Xv%Hv{(f0y6-Ul{~ z^{_95HO-=Ea^nEQ8XQI^G*JphW_RE8HrgS6hy>h0d%-G7NbQ2ro9Glv|D=|&M!>TT z9eSI9VSFwRtH@40e@@dECLzN-jA3-!1NIQVcyvO1kO+8dqmiD)`6PFG;YLIhM&pf;e)IKD@BaWGWCHW)JGpAkljT z)?4M+oi5M(LqR+vz(~M9zHOmlgiKAHtbbQQ1EwHC!{-@AAh6WrmxLbzW&+{KJ`&!Q zJv|dCYJy!zce{5^ULM=8lmmmn;>|v-2k)>Dh>mT0co4mqnJniPbTtW5ua}n&JYaQz znN@&|KxF86a;&Eg3)V;*6fY@CNdx59eMPP7aOilryzzwtOl<&I351AEV>V; z2o=HxJzNmm{oi+0*8f>4!U#P+a%^FrufEiAF?|aLLTfns<@9)ZVy=RfpD#VQdmXyQI^va~wBXuGAVr{XEf|a(Tlmymb<8;+alv`m0R)YrT>t<8 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 5e72c921f9699258fbdebc4149fc8b64878a36c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1568 zcmV+*2H*KoNk&E(1^@t8MM6+kP&iBs1^@srFTe{B^#(z<&FYW++#w<+pjA}xqASbV z_C!*C+}%dnk~Hr0Ew&3b0h`ecu+o;QbnoE9-ASF9f244Cmu}qM84b4%d?&~fovwHxDZ6i6773ti#?y9n4syt)rm2&3_D<;}Jns5vzYt_WoO&q@2s;NR#V_KQ zBFib?V4ZaJw!qCoOGc14Smd+eyfKoVfyl9}YXKn?xAPdlQM(Z6%X~N`!@vSk&!>^E zCa;$muU1Mb0^Q>DQrx#bofvX2FnMhvvAgjC|%k;m!vaq?gHfOfC)QAS%&UDsS*3M zjqmWsA&4nF1o}POLVr?{_2dBWk&l(~0D$>guAcpK zPTrpADG{M>N6*v)Znzd>{aFNufJ0}m)bm@&y$SQa@UyV>}mFHadPU$9kd6X$T$b|LJ+cGS*f95cX5|V zz61S0F7jC#?|{C%TWpk?GJ*dzEKNhM_2xK781ppWV;)wSNkm^UDlzb~V8*UTnXZU-Bn%EP(^BpE& z6>il_1KGP8x#no7pe?deL%~$@7vu8Imk~$;)kt0$q%n{Gfmoj}+8!@0vu@v!Dgt%T zn#gN1d8XN?f!=)a)D(fHs?7a6ML;Cb3v@;sxTDqWxQ{j9w&5MzP(z?^Zo{41hCo$t zRkKLnoOKC|FW?r+^4fx}me*PfJToyP`|4 zl%?|>pZtPAz$P#$*s2MQ&Kj6mDYV|fEoN?L9dmUpf$2k}`8yJOf;R-BUKi$Lc9jH1 z>yiB2@Qxk4Ygii?t-t+LXR47dwwi!UAS5sveBZoB-&I~bH6FJ1LgVv@z7p#G-sf;W zKeY46;QQuHVEpfGb%uW~RRoNGulM%?%f8%Q2i()G?S1wB*Z)pbnH)02-kuDE$u9_1 SZwaUb^yk~(R^jYzeJ22mh80c# diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 3d1622d6d025a6162d557b6dbe904d130e340903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3396 zcmV-K4ZHGENk&FI4FCXFMM6+kP&iC44FCWyU%(d-6^DVeZCd}fxBU_#Vgk79rkly; z_(s0bI16oQ+Z4ymA274MAl7uZ*@wP?-2YugJCdf`aQugvVX91FoKkTAQibNs6yBIs zW!MdqAtYzQYz&i`8N#^fFf%hVqq5;hZY0UFt(5;(eFqTHkoO(lJzYI>FCjOQBuA39 zh1m`2uFA~r1CJ=kJ^2c}5-$sqWYe~|aco@Mwrv~Fwr$(CZQJkb+O}|5 z&S9sUa*q(T>Fs3tsLHdw!nREq{(ra=P}oLl8w@4X2l~&zZ6ig=9y86%eE~Zj0#F7} z@qquTaq>LfzTvI%hMMDI61k4!wKw0F+ZM1mUx2Sn@hT~E>9W3=Hhq<4w$ok@KON^P zcXhkRbu=Qj0le8u<~%Dw=-nc|FOomPl!&Yrk@R!ds7S`Ip1)8e&E@Ch);VUxC`8nb z+io$v>lSBfh$K~ z6tsibv@sOPC6NpeWyF=~L_U#4r5U1Q&psT{(W(!E7$E|2a#$pTL|;zIkfbt`z9icI z!6}H2($=4iIf>{oZe}2st84UJWY;H|NS+gwrbwAmr9^+PjjpHa zXo!4XBNh-%BBh!{B$DP^5nWaL5PA<$X@(RlQ%c0mUX6~D?240zMB)lXmSvJ>3`fHL zLd3Hk0sqt#q;fo&yM9ngW}o&5n;gh4Q^dM{@?V>W<B-a-_3a&MaINfHT?1Z~Xx1pZ(ad#FNv6%rrD}vAchUKXeNwwgZKN>}aX)d56kvka^O(8Y z%O?ajA*KfW)8=?l62InI=hayM?(sv+V}`vOgdppt^AUYrJ4v=NTzVquRbn-9nd{7~ zOw+i4GB9*splyb2-+?9ei_3dR$t-LEJN#)8JmA?JmJk#P`XrJ*n$YcGA)nYHE>lyF zoMH(>s4&Qqp(^WRA$p1Y#;iD^i~_83ny*OG_|!560d5q;H2D8#W&*d?9*-Z>FQkA| zN=atVi=9L%H1ZMq6@aSN@pa=WxrkepM7t8kKCzVloCzo^8>-#sqlf9Z0b8>uNlD!X z(BM=ljk4-~OB|HRpfyjAird=b`icr`hF7Gj^`}n8kXvgf~=^e7uy?4y^&y z40A_n(72#;r_+g&1y#2`jgYd;fhC8K{p2>SOCkYq9{-fV4v{j^`-MSvJxP?*0mN=Q zYX7f5FNQAs2Ai8gt6Z?J3GS}2HtK2C5Cfe#G~&7VS`fEwLOAqAn$r4z5$f26t}ePt z#*=z0sLWtrM@g1lyE*3{qd5ED*N0(U7PzK)DiNZpsgXlRyCoFWhCJy^y04Xf)bWxz z>;0Y?+3v?#<8d9{)GE2VGNSHA+g2t#|Fk(b1952JR@x*yvAwFpIrG)pob-Ag_oQY8 zX!x(^bMw=+AzfEI2s)o+e0T+04xWk7b=ruN;TYzzzTJtFx$C8B<=5Jt%>Ks;cg8$* zx&D%CYZE4(nZ?FnMfln8tCkl2r znJK7El80PyFT_ZukGDFRGY=PKi_>(87|uNxd6rNwrZ7H z3#Kv>jT;mmmjWgC(umpv;41VY5;6Q-IE+w zV>;WO3h(-V>ys!>D;y0h31hE1t_G)`18{O05$~vosJ)btn-`X(PD~vV|FA7oA=DxbCidA3pto-$cTT9);gv184-R>)gNv zq(DJb6NeV<;%vQ*9ja=o zfy2QLViHsE9nMchd#_{$C?(G;R(n#z;Rzxmg2p>G{nYp;T#d<;I~c$))P9raE?OQp zno0kT+1J45T{$Yy`RT2LbBIX|@Qn!|ug2*djq2@5@;y&??>nX|$r->b{Ty7zM18OXOoptmUo2 zS27e7Z=Jt>_H7pLmdv{sz$`HRyiet~lH{(Zih~0Zi@-PY&6s;DtlmNK0JuK^SO-Tx zM_nnI(j=ldf!&pTeA|BkY<}wRp;e`U2zCar3y#xeQyiyP1KRmVSpbeZAC;E4p9G** z_k{#NZ$WUB(Wf#cLr|3+4rq(YKK|)!0GF9xim9#zl+aOP5{wh0L#YDvpCeQ?_;@9lV`oP zPjJ-GXrE;d4PK|js~`dJYKk6!c`XjF;_3HM4f$!zP1~eMc6OTmb@9~4njAjepMP0N zM$~BlR;{27U|dyj-y1`AWmlTE2{#HAe7ngs>KbfU74+I%Rkp)6X=QgNJpd9Y8E_i{ zSXAS1D|-5JxawR&qggk7nPj+q**2qT$p%Hwy!yfFi+g_Usl2fYfB|r71)Z|}>hKck z+j%eC?&!)5kT{{T-&$_4zs*h}d*WWc8TV^*gzs1OF#sn~n4+k!0VFj=AHcM#4o67w z&I_UGvZw}TfN0tUT%**tcEU|<``gqe7fd7KF&GL47SFs`hnKLb=f++HK$^nT7IFYA z09j2icy7OH;L`ZM*ZCdq!qZKLf>8^IXxf#mo6csln`{z`+vdt?L}ZWZ8fi899q$%b z1K0hYd+HwmRpe&GV&9B2zSax>_PlMT?jLu_IokjT z)~pq@pYH@;1y6)gS)%C+mWHjs3}r5IaQO)8=!7{ ztA_AKSXbkXyX_O9zY}#t?b$KTR84|wbgC?($j+KKu)|B_?l2+F5T2^5F?KA%Ep*s* zQYOXS-5GR+2e%0~@4)>?Lu7kV7b<2;O_OsNC*(^n{Uk5X?a^_5aTDHWs?EV;FIZ*!+7`{;W-`kOr8 zQ@IXhYH`S;_DR)^=()2gb(&JoQMCSqQm5<>XC19iHEuXmpCfJn`_rX4-bs|Y&<>rV z>>xe*8RB>YBXUyEPuahC^7}^|F%G3`)72|YgQ0f*s#OVe? zBl>g1+8qCgp%KxcgMJ>>E$Z{+aOanEUG}H@QRzA&QtDS|#2l2YoDoBLh3>!RN8?HyUkLQd zE05{VPRi*Xb$HQ36hi#}p=8iiS(RlwyB4M1;jOWmWv4Kkbj6gaEz2ro4*SsFLoErWNNM zH;)8lTDYSpwkI<&FZVCoUra}-mw02yl0}zWOgUs*Y`U*(Ph@61=##IDQjZx|Tvlz% z=mQxSoAiY3V5V$_qEhN6>x!#tv(ny>b+M`cjzPs__(4_qF@MA{gE4C!v!*e~yx7?1 zj6hgs3$i9_9PbA96(egM)1GO4JbItTzP79#4MFenJ)TapWr}P+~#z{jRK>*CrK~ZiP0d#ARV^)pR ze3CO**|{A-5G=hmMOkbeActqPk&LP$8o_@dB>Gg2_YBY}bj!Oa%Eos=1aVo|7YPtj z)};A3-Yzgc91~?oMcL7v5Jb0TQ!|PEB)L?LlP99=H|Pgpnl5{}gQD#AJ|?LGf*-Bq zTca(drb-xBIcWjZonhhSP92~qPq>gcgmH0fCUd2lDPfL{ovQ?94vvAcqTUpTmfc5t zgqdO$gGQYq;-{!8r8Yy^aj@;-KAh}er?E+ZOpS%LJD`fT7T=@)fobGnC`6B?tip#jN#CAZW)|kxw0affc0*&JYL|fg-l}+t3b~XeWwu%fs zMa7v+l^)Flv$JzJRe&p}gyDt}MnREDRL#iG@uAi{Y`^iD6rNVs2I>V4w21Gb+$pqx zh%G_2@pi``!Z1ChePQ6UcMOvc!9dw46|k}C(?itpy+cU%JElf}5cKo~91(_Fzs1u8 z@JU*EZx;a6eM_@=jR0XZ&HXqh766N$mdo2I0@^o*Nt?ieV>`;IZi9~;psWc{{qc$( zKoQiJjg1XK^k0u-a?A-F*=;`xh(Oslp`sU^<5U2`oWdRE9|shiY&rRFV<4KQx$D0y z0%__hr+`6mqrKk8q*M?_HM(IXcik6{aO_c-3c^HHwzP}lRvVdRJZdn(cV%?UhzO%; z1PH}RCtzkj=z8a+h|t>l^(r866jSOv0m2G*Rn=&wq(|>TW*=ok^EwR-VtB%}jDeYK zR)37D%%TQ_XIt5Ikg|iwo}t%0MiHmexUl**<6;9?ic3;r9jyXmdyi0pBVmr5gf@Ky z0JiV-&C8`Ns=4-gT_-^Iag2)jVW9ynK!DJkbP$04x3`lbL7UuVawdSojxju06wri5 z^#2iqQV-D2m~pEutlXaOph(iL_c6b?u}YZl&Qu}Y;2cP zyP!zaDPvemoAIl#g_C}vh5a)|r*MGa-;e^45p!-0#wX<8`_5CupfJ#0@37=P#wTJL zn3tj}HjkXS0J&DG4|3`tLnf}W@Ekka$3H7f^me_>Gj4(`3>mCbY&besfHNmRXd5+? zVdMl@mQ=?s?juQIrlf7`^tt0yV|X|N7E=66|Cj{9XX{bG}i zt}6tH7~!Q-BLs-VNqq4{t^^`c z2XQF-A^N3IJyWOoRM_w=d%Ta6$B?9e>L;H4wbnRht_d@6`Fm*#pIP;!iIFrC;Sttp zC!^FWv5bN8_v4a$%2Mj+wxwN8s(6NyP7cEjtZU37%1z#7Txzdwr-;QOzG+sLAxjXFoKK|lzzH=UNGjN)&%j8YhDTu}V*1SA# zE|2&1z8a^0w! zwdeN|{1b{#R7F-Evr1ZG9pN?4w)Qcbo#nmb49Xi`#g|=X_~U2o)WroW`9lB#gz!dJ zW}?&=few`%{H(>+w+T$Hg{tijdYu;;hn@`+p$C)_?8COWdg*k|$^#4W7OIpbz~zBTu2Uw8NkwwyYK z{j9dl!!tU1rPdf6`w0+D0R1O~BR~|ZdKSZTVD%sD>^@ljwr+o?#nr*=)}9=EoY>UL z@AJcR4#6+LF)BE^mM%&Sj_OZZnXUFoKe2D1g`0j+r)+g&SzSd0K zw4yTmXTd%(EUS;RV|$OVl3H}M%@%;*@6d(O?fKdCPuX`s;GQ1!9T5l+!)#54cpYQHDu+oD{n17k4~hNj zD#1>=;-a#fQw1RS6)wx5Yy|SM)A&T)#MZU8;VrvtBQ0uC_D)$(B!EVM(A_o7o0XGZ zqaUFB?uO?js`+;7>{ok`M*}9;yGC^ic1M6PngHQ!0>rmTM;(Cx8kgE(#ITMre~$p< z*XUE{36LmTAX1hC1YaT&AdcA_0|WNei+eUP)A&V*0Da01TGe!kc?5_}@F`M2@O4Xq z@8QdI*%ecP9t-sU67JX=9(^GMzkwzz&}`oNWdvU%sIn|HP)>j(HtH&n!6lS?LSbHF zLFEu(`ugx60;DYWYJxSNgp3A3 z790C1*mKe?%))1tZNQ$B8p0R#8o4tH1G4O{+wg^$1W0T&7rtdG!f4J3Z|BN@pATe% zDZ0ekV>f&umTO;lay9|tHTN#Vk>8<$-{xCf+1M=i0Tpdh{b<@&t#xU)0IW%fU-6=UDf_pw_6mDWw$0w(9sBxphb2S?&+UUrmgF(;qG9_L6a)b zc&vVB0!9yOA_(+N5OE2R!lc|(17sfb_)fO6%UCHu_7E}gJsn@a?|_(poTcUxAX-}E z-es-o&p>93l=F1jvu+P$jjk^Z$Ev3#=BlzR#tsfl zK5^}O| zWgs=wDK>GA0BIk#oIfrq2|>nb)o6AFi~CEmA86&9e+8Hw%9#4vM=RGXVof-^u8@QP zsbk}#QwD=z0db0QGLZ9DK~(vaulU;Ruqw;q4FSSr5g;i6(ivO_9tR@fjGYvvEy#u$ zTX8)809lnhD|*UPb{#$5yk_Mih}F2Qa>tW30o0=!6;DQwRj6xgfjOe5boaGi5ml$D zMHK{ynTE<0+}_wF06`{KuvzVPUr|>`+MVkhDXyZ#I!224nE3d6$z#4fblK`IYa25L z3iIPco>@g_n;zd&Vv(y)nk%Ct0W#r$Az4*z9q9>d;e5$O`!2JD!@^GS3OAY$t~ zAV9|0s>3Nk=I?8`A?Ed7V#`kuAoCrZpwPu9)u`U`V}At!vgnH!JB5-N^De9x;FOrE zYXrznfYiq>_o|xApahDt2u`wr>H&ETuK!qpT0t202mOzl?n7+$; z>a}67qDJSPP9dhOptm_BF|PW={RXp2^jgPAS=P5Rh)oHncIYYo@(s>^*-lteyH{nq z{^}jKK0dyu4yj>w@2FJ66&WXtuLtDUJ1<&A!5nrhB1ad7A2nE|mtU<56pTM%Mnzba zWrn4&x{i^G0O@N1+4S~9Uy?UiGPC!=9fg_KpJ#T9^*L4x$nkOSRb3cn`ae5pYHs1M z1UprHEg(yD=lX)T46-WE$1V&_rs#^zwScVgzcOrLuByp0<5JzR*IGd4==O={W|IUN zF?|vC80l+wFQlgG|4l-Ym0TjL$BU>T?xG$rGKr zz4+WEZ&~$|G4b8a@-#^Q{e+9?Tvq7id%>OERi_P9tB|=k{a2#Pmm6G<3hoLA8!RW8 z(W3hs`Geu(+|Qw+%U3jnRZlPOd7xugcjwj%n=Lsmsbl`&V0hH3pM2e$tXC+I{`=i}J@&8%OBKlJ5zdIWBI_v+J5a*!KTjqT^;o;h1ze)QSRyxRc4b(`QD(o^+IV) z*E=_8lpZGC5g*^GbH>30B0R8>+jn-^QxYIi*Z73uQpZp&AWx&2Rhsth*rI)Gbj8vb zpPezu(|X5Ez3Z+~`N-&cVH97RS#Qm%wW2Y6VAr=l_(aBX>P!x`>yBv!XhJHQ?E zdi@E{({pigX=&;6IONDwT-@{XBwT;5cW{8T*42p)k2Bu2<@t`j3(K=Q410oyJ@x@w zb-jbH=(X4Q_+ESciaY4q>Hx=n*b@xfA*;NwZ(&bda0DV@F9E_5Abdr3c~)Xshm7iB z9jeagP?nfgo?Vezx^yNwr$(CZQHhO+qP|Et+k)Ep8LMnu7W2{I@`9bYT95Yoy{(tS-W&n8LOMq zMwR^!cRbgw(m7f6c*@wmW9KzY7o97%PZv9>=CZozR56E@XS(>LO{d*GQKc%S`2z9| z=1S*epDUH^bk?bYG1}cv72CFxUKOfL7rX)IiP_tgozk{nLUQ_aPCA#WQyCpwJ6*~h zyR=a`lp{%UBuT+PRm;Tw_lpm9ntMRXwJk}KRB2{zKHIndJ-VA|$DSn$pagOR0U#j9 zR&3k0oyxXdT|VH>wr$(CZQJHzAW4!NwwWah6bM2-i7@5l0d}MRe-_*MT}iCpWex5% zu)wMV^`=(H4QMEV0=9$eD1=C(ScANDBBh$4f%itpFS)!(bu!IO zkIiKWRm6_MjR~)^J&_zmaEdsJPy;7=vvW400p#sw$S;aFMB$Bh0Iof zTt*SZCsm|5TY)Uf_Q-pS3Lv}wvN9b|#xcls!0ACDno$WfAtGwH!$$IoyhL^tdE}u7 zB4vtJZX`*LB!&LEod!?he+o_|s2Y>tHj*RBiiEAMN*9^6=e<7(ux*=;G-}(n8MbZP zwr$(CZQHgvwrxAfg&;|8+-5-*fyDxHPU^5fAoh`hOu`~f!lF##|7c?%Uo3`KMx!KK zp7{*Ehs7EtQ71{pmJOC$I$1LEh+G|uO!4*_dEz4Lg)jiWrv;u zcFqwDyVTvfbm{!VZtXy=o$dWRcX+hM=hp8hg+Ug@mX%a(^xin-r_Let7gRzh=(Y!! zfJH8yYfcTlACu`@%NieEe{-wi?!xghIK5+P&&}=l=5S5f^`LhA?~r#&XbQl0^EqX{fYyn__=X$g#8YF$oqx|zTjq^85 z`FK?wZ|4#SYv#l1@b4&}hI8?y>r)z8717Bv5xS*{M<`$m!lgv8IMm^@e`Y7D09ik7 zB8xHyyCZZF*9gEF)GlBf9Fdc{$)ar35AUluy?v_DKWzbzyh09)E47_1z}R1<2Ts+< z>v!`U9HD;zO#(J~jkp7BatrYAgWp;d4YYfepX!Cs6982ne0U=n9?nOIYH-rUQtdQ~ zqC&4ALhAtj*#qE|cM@+AypM4^fE&+T6pi$TA=ni?z1CQT6(1q*A;2q@bKFm+G)gv# zb4BmX(O88UpG7{3uYC{1x~O000pu$D3>t7A+d6>ZYMA2yO-V zClDcE7ynd%h&~K};5J8rY@&gp{^}#bKW`3X2-y%s7E%TAKY>G+6t0rAG}$1cr>dO3 z$Lbt}h&rzboQT!KO@c!2i2~N3V+)myB4;&4=smm@h$+E5VyOhggg*KY9C~kVwWQ&` zvLq^BwdVAGlI)OHFUj@>B%4C-Cr7mxC7JkGMo;Zl3rzw+vgs+ao`9g-0*C%6$j&n9 zp+Q#oYel$2HZwT@;pQ~eK{gQXH`=hOlZJ3pNI!=w8;Ex0yHyZ;OS(HlvY#p2o`7^y zQ18q+wPXXy{RW|js%&JLS-v~u)`K?)kkwofq=1jj|Ep3Wsb&< z^8*0l&0M_fMIbw&B2p4%ByCd7k|t1>imoYpn}7sBT1|3@ncp^RQ6h0eQATJy+}xHp z!MW6QuIg)o77z!)@Xa~M988l%nM4LouOGn8fjFTV8VFZ!m{65~xSWGRml*^N~JznM|>us5Tq{9|bdT~Y;6Ky-OA7QPcuAh-WFr>>d) zYguHx31nI3&>T8C zZW-&*>cS9uPKosfDsLOc%D&Jp(BX0_zB2PJBAdj2F&OV9ae6B$=@77>@^g$;e2rf! zK!uvzg_&xDNm#Tfq%9bPTml_{D)Jjdg;d~JREiS)IwE%GC z$}2IPkr{HHvz2VE<}bfC#boM{3UsWDt|0*Z`Nkz?Jy(*6YPIS!oOPKxXlv+RlS zDE*$CN$4@FGff^c35%0uA@gSaqwd3@2Ws$NQ1dxHD!s-}6>4xkR;Sc|&w?$5B(b*U z#F-Rjf#iE*yoxsupho{xP#kA1v$hs6??^xLBlHaHs38!Sa<}29qz!(k(36-$%!F5- zm?b2W_%~K(>rC# zOA8?yYCOlZs)}ny2DB)17T(FL+ck`V?_?v-tg#Be!Jz`5B*koCIw-Fhyp~WC?3a%A zfw$Dbpk}eOBZE+!W-qRFp`J5I)ke?O^Cj`Rru`EdZJKrEbR;{6NVO6P$7!%kCry46 zv@D*Js{yMr>mSr8=9IdV$ZR@+8n(rBRByYXW$T+K%b2qh`_5@aULeht(i%d)G%l_c95KtaHkz z^AYLl4^Y5#Opwy;#b=0;q=d4LtIOI;MgUT!?lKx(UFA33+k{c)naq3fMM43lML&_= z1)#J$Xq~B(HbFEp4=rZ8Su=sEFHGJu&@fy)D0ROQWh3fZCwfoGpVG^)2y~rJ85@{z zSrxP0>u9JQWp2E9!aijZ|HNsV>77$dMxPM%BNd&pJ^$JSr{(W6DGAKGV$ZPZhabn+99Tvm{VoO`J49K)(=ugSOOkgKpAwxA9$r4NC8O9K^Gvma#?}7q)vLJPou z5&$v%HlKAT`~VOEP;jr-kcf0~jKpdy zZbR*77;#m9ZjmwM)za|r^Z#jLa(a^2=Ea^Waqs{jDulhhO*FS$dKfXIL{*+!WlVY9 z3@|J1C!`&du(WGi^XB3JXgG8pI5C8ElL^f!t~?69u9k2YVHByJa5Y4e%SbwEK%%vD%6+FR?9&h900e-6l?lRA!CscEe(I=}G3!5(eUIGxfY6=(o`M(q4 zVV_OV%7iP!R-sLZlb&JXo{{@nY3?)Km{F`sugQ9*1Ll$(?u28^<@o})BP~FXh zTYiEhi8V0@ei4AXuFv2n5KUe=&Xn(TrERF?9MdE1_+)v`kaZ7XIz4o&E_8pUj~dLB z-vsOG$x$HQkvq3;wA)P>PVv{V=1h7i7DOS@hBF9^ydR3)4BX4O+E+uW<-3pc(9({t4wZcG(zQ`Uy!x9cKYr_i0+ z3OtKHf~NQ}bNvs} zO0OwlL#{J8I2<`7gDdZlb~P}g0)jImFAn4k0JwCK7gMV|T$8JI)4xwSO#et7Z+_vH z4O88G$rCm@eTPr=uNwuN5$Jz zch0rGQ}3A_U-BRQ&9IjUGTEGVMGJGoe_`hOBlI#f-^hd;&7vIzPWq{1$gEDg?=^p@ zw_4BXE7vOdy7YTlb3Apl2M9X@BPokYhoGJUBe&6wk z^@$qJE#UXr&2-K`j_3hG5;-xx4%s!C0sJO4e~jb35xj5Ouc?1aO|_QSR&}m1E9&>n zUtPB26nk50sD??{3*I+P%?|_nD4YMpjPG&i38uQ`0q0DqmU;e%W~y43!%QjGb{rR& z>K0SuCBGZP3;+^yzu@7}EqryOo8bm5SmkbaM`2p4%FiuwU;zob@m7MbZZy?>&=bS} zD5^{VATk3mDWr3F>vk87$B{>Y6KXkg5t^tsObfq{wXP5ZyT@C%J62u?;4pKH@B%O@ zbeFUX0D$2gIky=aqlF{nJVRV{xx@XvFYd>!o&C0UZHe#DzLb-Dde{Y4>*hTYSe7*x zyP?)IVq2!BBd zKu4;aba>y)eiO;mR>?M2BzW5g6VEL`0l{-KnVKN91s|p(et=ID0JMUY+I@9;-*Ou1 z^fFld)EaK3_aJ(1DVzG%e`fY#llU!#mmmO{u@@6j&OD+Q5)0@x_ZjL8hqye^_l-b+Zoc*9ah z0NiW)ge3CO$!GvrhIN~D|J-B~m&12ryac}m0ECfiKoSkNM$-vD*EWeS-ASfn5O~*u zn{Qqg4+DrPkEVbyN?pR-5#dI@bBx#KMRxc>PV6)tnfn)o$L7b`7>?6`lTC<*7w59k zzy7*g&Ln=MImrC1-8GOcJ@WKJN~nADU8T6~gqMdi@>xQ`d*}EDseInMTha9cEm)tm zP*Z5;DIo&p7m)vS0@Dxn^E;*Dz4;-`wFAIYXw8}*X(qtX2W0MiMBcVDm_nx$##S^= zk;u=ii{p)fn`R=(BL71EZ|DG6FookXBJUgVR#L=tLS{Fr&QHUPRD&C`1-1JAK(AWK z&$XW$?k16P--k#f0ANjH(7pfV20#VzG7&xR#FfIdO8!8v0f0+BJ<2YyXjoU<(v^)Pz$c%Y zM5Y*ErU%eQ`4?23n$=ixt>{!c>D8LF`#&rI+_)oTgLO_#OSZPR@l#j0*z%(14?kF` z8wNL0EZzTMRqLuXDFD5#tDxk%chCtTa6|dm@N+WXDD+rA-hSM<$k`0Et{Q{@R9z43 z9&%K*kztXs)O+D4_B?k z{f&Re+6NSiTC72F!3H2Gb&qWCS3rW0K&u4`UWzeod7qLU1O0_HyoH6 zyC_!!mOKOyT`?r^m8r^#W`PO zc(jYq5|NXIBjsw(HBOI}YXDcC0f_s;YHAI|#?FDOD5?c2rU~o}DwsxD7c?pOhM7@Q za+#zSVPGw;*g0?;HBs}w|FHmw$tG9J3ctaj(nKlAYX?m-orNB|E@|!QEnxr(m0I(q zS^$DGI#hR6jQ*mNPNX(Xf-umt=SW?D`Dgx7Ah-(E(Nge)Xd0R2{jcLk^0bcW?7_Gb+yikOSulg z4ZrZMj%(BcOFyP2*6PUHbOQ!^)FN6N~$)- z*hP*^OT{8r1D3i8Y)o;*NXw6Dp_&+W=7%ob<)eSfxj@O1eY<9?nrlKZP~s~~mH+zQ z49f2`n3?iI_MUWc3+`$^>r6D335|)d3b$#V4qtp++!)*vO*8E|f|7Uv=q&(3JU~mW z8`EfPKE6O7WUR~$v=m%e@*WRlrz$S`vvR?PivcjV8^Op>++F7RjYh+E%i6$Lq1#d7 zBceb2T0o@T2svXMwPI-XWFY{UupW0-tt;o^XIKR6bBraB2PHmXvqk^?K!M?e7sHau zDFD)>a`P;O-r!K6QtFK{8!CJ<4@eS+0Ekl(j5WfSxLbe;M!N6OCf(1bUyJ}Y!>sy8 zMY)SRUv}MN7}?WuGt>xQLQ%GMBcc~v_}{LKfX0T^98K^B8a8|)`aRf)(m%^qNYX#* zgw3@A98myCNwZ)V0=v(1jyj}GQ1F&bssdr7a{du33>+?3%$bM)NMVVdBg(l1oi_+p zP<^;!Cv-!axfz)RqK(nXh{t(4ULTf(Rbx83Wfiwp)|E4O(goNihVHm8Sb`O@cu6Kg6{%y94y=ouc#+3{! zZ9x=3q8ryHta}q7+`*|s3IVqiMm#TpZ~v<30`{yXN5jTaL^ z9|eeFKR^f4$7EhqzUJSup1-Xn%p}4a<91fsKyuQfnVn39*MwU(Go{xP*?-jbNiQ?s zdN|QzvJIpvPIp!9SeRY)q_LH_rU?&cb~9DJ{{QZYvPPn_pY$^GoqI8QHSx+s+DPp< zSBfNBDp^Pa@bw|BToWEmba9+`@yXpI7$!(0c@eyk-IGrJ?j{c9Nf(mL9k3@4cwX7) zzh!=xBhS>`$fBp9T!`hETUe4r4)1O}awrwOobR zZa*_FNnY({={I!rFGZY;LI-DL|c$*bboU4XU6iPV`D8nAXvVKChRO`rkaH1){`obMo;X)wEMn*CXHo zj^rc{kbU>-rNa!a+L$x5ndivlC z7Ic6QG({xG67GCHxE3Co)F%QLk2VP=E2JxVUO}vNv-Gg$7NycY8L+{gfY-k+Ztiwr zhHJcnj8xJEZ%Q?h7)AgV%hY&-2Pl!Fmb88jYv2voo!D2J;+b{A`gwceGSZKV z#z-2&z9?{{8jk+kp1AXd)D6?iS|(?O+q+zTKIXi|f8EE?_-)h|HYPQnL`s-yELWSz z0vi$fk*L{0rhXk!&V{&E;VT8}h>f%B=Ze>Rcpx8gWhZL67yxNqHPIQ?5&(T5amx8? zj=|gBSn721rDtlhXl7VniN_B~Ex;V-e9Ygm_Qz8a0awXNn+Of+h=rCfI)7`D2iVWz z(VOS{7qusFf$=7b<>%w6H^O+$k3z2bsIOHpb9N0T@%yHd?p)22r^w!0rjI7AAG^wN zZ8_dRm^@?cp@)M<27*#KD^-? zsyATGJEVo*HO($kgh?07B3nKpRpGGYU16=McaH_-{V_Y0sD%q=E7eo8)9h3gIcuJ& ztjpnO-h!<(uof$7&JnIx<462#Cay|pwQq(k4{Koa51#V$|1}*BS9Z!%bE>M;SlS15 zE*ZPHwUU_H;^Gx_$kFV*$9QNxTasL%h(jA}oOT$~7`3#Ycbql(DMk`s8CuWX*K~yT zy0%OuR-6~dl3bnU=|NL-oV7|c-*_kGH1`Q|(#44x+2GI7cl)T{@UGMPD+J?KB{$oSh2ND|Ap=VJjKpwXn5 z+-mle2}>Z%?CIB_WHh8#6488ibuW*NqEd%{(SOT*a4l2R=*1ixc;YS*eR$*e(h<1^ z4o#OgHfZEn&;S4T?BWV%tuKv#oQOW)$-94e@B91j#p4&VRPMyyRee61SVpHUJU05BjV%=8 zqx5cXHKp#I3>`a74nXe=tR#w4k@*I&k+~BNN=n(`*&p44N2Pnw>tdPo+_LJqW7EU2 z@EN>gwr-(#Z!!)l8U!#Tsn1!Jt_O端末の設定で変更 メールもこの言語で届きます。 ⚠️ インターネットに接続されていません - 手順 - 開く よろしいですか? 名前 名前を入力してください。 @@ -41,9 +39,6 @@ メールアドレスの形式が正しくありません。 パスワードを入力してください。 パスワードが正しくありません。 - 権限 - この操作を行う権限がありません。 - キャンセル OK 同意する @@ -83,7 +78,6 @@ 店舗を追加 店舗 店舗名 - 店舗名を入力してください。 店舗名が正しくありません。 店舗の説明が正しくありません。 名前は1〜%1$d文字で入力してください。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b70779..b6cc165 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -28,8 +28,6 @@ English 日本語 ⚠️ You aren’t connected to the internet - Instructions - Open Are you sure? Full Name Full name is required. @@ -37,9 +35,6 @@ Email is invalid. Password is required. Password is invalid. - Role - You are not authorized to perform this action. - Cancel OK Accept @@ -78,7 +73,6 @@ Add Shop Shops Shop Name - Shop name is required. Shop name is invalid. Shop description is invalid. Name must be 1-%1$d characters. From aa20b773eaf1780889a4bceb5950ec4ad98021ec Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:10:43 +0900 Subject: [PATCH 5/8] Remove model types and fields nothing reads - Shopkeeper: no code decodes or builds it (sign-in, sign-up and profile responses use LoggedInShopkeeper). - Shopkeepers and Relationships.shopkeepers: organization membership, which the Free edition does not have; nothing reads the field. - Attributes.shopkeeperId, ownerId, ownerName, isAdmin and shopsCount: decoded but never read. - Data.getCreatedAt and ItemTag.getCreatedAt: no callers. Every Json that decodes these models sets ignoreUnknownKeys (networkJson for Retrofit, and the demo repositories' Json in tests), so responses that still carry those keys decode exactly as before. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- .../nativeapptemplatefree/model/Attributes.kt | 15 ----------- .../nativeapptemplatefree/model/Data.kt | 2 -- .../nativeapptemplatefree/model/ItemTag.kt | 2 -- .../model/Relationships.kt | 2 -- .../nativeapptemplatefree/model/Shopkeeper.kt | 25 ------------------- .../model/Shopkeepers.kt | 15 ----------- 6 files changed, 61 deletions(-) delete mode 100644 model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeeper.kt delete mode 100644 model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeepers.kt diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Attributes.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Attributes.kt index 7adcb5a..3622bdf 100644 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Attributes.kt +++ b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Attributes.kt @@ -41,24 +41,9 @@ data class Attributes( @SerialName("account_name") val accountName: String? = null, - @SerialName("shopkeeper_id") - val shopkeeperId: String? = null, - @SerialName("shop_id") val shopId: String? = null, - @SerialName("owner_id") - val ownerId: String? = null, - - @SerialName("owner_name") - val ownerName: String? = null, - - @SerialName("is_admin") - val isAdmin: Boolean? = null, - - @SerialName("shops_count") - val shopsCount: Int? = null, - @SerialName("shop_name") val shopName: String? = null, diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Data.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Data.kt index fa498fe..b5bd0c1 100644 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Data.kt +++ b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Data.kt @@ -14,8 +14,6 @@ data class Data( val meta: Meta? = null, val isOptionsRevealed: Boolean = false, ) : Parcelable { - fun getCreatedAt(): String = attributes?.createdAt ?: "" - fun getName(): String = attributes?.name ?: "" fun getState(): String? = attributes?.state diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ItemTag.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ItemTag.kt index 5149da5..3b24ca7 100644 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ItemTag.kt +++ b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/ItemTag.kt @@ -36,6 +36,4 @@ data class ItemTag( fun getShopName(): String = getData()?.getShopName() ?: "" fun getCompletedAt(): String? = getData()?.getCompletedAt() - - fun getCreatedAt(): String? = getData()?.getCreatedAt() } diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Relationships.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Relationships.kt index 6a53ce1..eb0c2bb 100644 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Relationships.kt +++ b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Relationships.kt @@ -7,8 +7,6 @@ import kotlinx.serialization.Serializable @Serializable @Parcelize data class Relationships( - val shopkeepers: Shopkeepers? = null, - val shop: Shop? = null, val shops: Shops? = null, diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeeper.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeeper.kt deleted file mode 100644 index 7c46a9b..0000000 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeeper.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.nativeapptemplate.nativeapptemplatefree.model - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -@Parcelize -data class Shopkeeper( - @SerialName("data") - var datum: Data? = null, - val meta: Meta? = null, - val included: List? = null, -) : Parcelable { - fun getData(): Data? { - if (included.isNullOrEmpty()) { - return datum - } - - return datum?.updateRelationships(included) - } - - fun getName(): String? = getData()?.getName() -} diff --git a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeepers.kt b/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeepers.kt deleted file mode 100644 index 990f7a2..0000000 --- a/model/src/main/kotlin/com/nativeapptemplate/nativeapptemplatefree/model/Shopkeepers.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.nativeapptemplate.nativeapptemplatefree.model - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -@Parcelize -data class Shopkeepers( - @SerialName("data") - val datum: List = emptyList(), - val included: List? = null, - val meta: Meta? = null, -) : Parcelable From ae9f7520afc7cb439aa9f2b94a3ed40fb7cfd2c1 Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:13:04 +0900 Subject: [PATCH 6/8] Drop the parcelize plugin from :app No :app source uses @Parcelize; the Parcelable model classes are compiled in :model, which keeps the plugin. The release R8 seeds are unchanged apart from the classes removed in this branch. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- app/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1478f57..c1b5372 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,7 +2,6 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.compose) alias(libs.plugins.hilt) - alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) alias(libs.plugins.ksp) } From e83aa0918fa59bbb13ff1f74f9c8245e8a5ee5da Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:16:15 +0900 Subject: [PATCH 7/8] Remove app ProGuard rules the libraries already provide R8 reads OkHttp's rules (-dontwarn org.conscrypt.**, org.bouncycastle.**, okhttp3.internal.platform.**) and Retrofit's (keep Response and kotlin.coroutines.Continuation), so the app's copies changed nothing: the release classes.dex built without them is byte-identical to the one built with them, and R8 reports no missing classes. The retrofit2.Call, GeneratedMessageLite and @Parcelize rules stay; dropping the Call or Parcelize rule does change the dex. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- app/proguard-rules.pro | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index a0c9508..836e53d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,22 +1,7 @@ --dontwarn org.bouncycastle.jsse.BCSSLParameters --dontwarn org.bouncycastle.jsse.BCSSLSocket --dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider --dontwarn org.conscrypt.Conscrypt$Version --dontwarn org.conscrypt.Conscrypt --dontwarn org.conscrypt.ConscryptHostnameVerifier --dontwarn org.openjsse.javax.net.ssl.SSLParameters --dontwarn org.openjsse.javax.net.ssl.SSLSocket --dontwarn org.openjsse.net.ssl.OpenJSSE - # Fix for Retrofit issue https://github.com/square/retrofit/issues/3751 -# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items). +# Keep the generic signature of Call (R8 full mode strips signatures from non-kept items). +# Retrofit's own rules already keep Response and kotlin.coroutines.Continuation. -keep,allowobfuscation,allowshrinking interface retrofit2.Call --keep,allowobfuscation,allowshrinking class retrofit2.Response - -# With R8 full mode generic signatures are stripped for classes that are not -# kept. Suspend functions are wrapped in continuations where the type argument -# is used. --keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation # Keep DataStore fields -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite* { From 2a3e764e0ba1be38cfe1a014ee867c780d2a93e3 Mon Sep 17 00:00:00 2001 From: dadachi Date: Tue, 13 Oct 2026 09:22:49 +0900 Subject: [PATCH 8/8] Fix the English text of the sent-instructions alerts sent_reset_password_instruction and sent_confirmation_instruction read "An email has been sent the email containing ...", the reset one with a stray ". Say what values-ja says: an email with the instructions has been sent. SentInstructionsMessagesTest (as in the paid edition) failed on the old text. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH --- app/src/main/res/values/strings.xml | 4 +-- .../app_root/SentInstructionsMessagesTest.kt | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SentInstructionsMessagesTest.kt diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b6cc165..62980b4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,13 +46,13 @@ Forgot your password? - An email has been sent the email containing instructions for resetting your password." + An email with instructions for resetting your password has been sent. Send me reset password instructions Resend confirmation instructions Didn\'t receive confirmation instructions? - An email has been sent the email containing instructions for confirming your email address. + An email with instructions for confirming your email address has been sent. Update App diff --git a/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SentInstructionsMessagesTest.kt b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SentInstructionsMessagesTest.kt new file mode 100644 index 0000000..b39fad3 --- /dev/null +++ b/app/src/test/kotlin/com/nativeapptemplate/nativeapptemplatefree/ui/app_root/SentInstructionsMessagesTest.kt @@ -0,0 +1,36 @@ +package com.nativeapptemplate.nativeapptemplatefree.ui.app_root + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import com.nativeapptemplate.nativeapptemplatefree.R +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +/** + * The alerts shown after Forgot Password and Resend Confirmation Instructions. The English text + * says what values-ja says: "パスワード再設定の案内を記載したメールを送信しました。" and + * "メールアドレスの確認方法を記載したメールを送信しました。" (an email with the instructions was sent). + * It used to read "An email has been sent the email containing ...", the reset one with a stray `"`. + */ +@RunWith(RobolectricTestRunner::class) +class SentInstructionsMessagesTest { + private val context = ApplicationProvider.getApplicationContext() + + @Test + fun sentResetPasswordInstruction_isOneCleanSentence() { + assertEquals( + "An email with instructions for resetting your password has been sent.", + context.getString(R.string.sent_reset_password_instruction), + ) + } + + @Test + fun sentConfirmationInstruction_isOneCleanSentence() { + assertEquals( + "An email with instructions for confirming your email address has been sent.", + context.getString(R.string.sent_confirmation_instruction), + ) + } +}