From 839c0fe158cd8ea7b287407bdffe136ce38f7252 Mon Sep 17 00:00:00 2001 From: erdo <226319+erdo@users.noreply.github.com> Date: Wed, 12 Feb 2025 19:34:44 +0100 Subject: [PATCH 01/42] fore-core 2.0.0-rc.1 --- .gitignore | 3 + .../example-jv-01reactiveui/build.gradle.kts | 92 --- .../example-jv-01reactiveui/screenshot.png | Bin 23237 -> 0 bytes .../ui/wallet/StateBuilder.java | 66 -- .../ui/wallet/WalletsViewTest.java | 150 ---- .../src/main/AndroidManifest.xml | 19 - .../foo/bar/example/forereactiveui/App.java | 26 - .../foo/bar/example/forereactiveui/OG.java | 72 -- .../forereactiveui/feature/wallet/Wallet.java | 59 -- .../ui/wallet/WalletsActivity.java | 85 -- .../src/main/res/drawable-xxhdpi/moneybag.png | Bin 16471 -> 0 bytes .../src/main/res/drawable-xxhdpi/phone.png | Bin 13455 -> 0 bytes .../src/main/res/layout/activity_wallet.xml | 100 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 7805 -> 0 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 3633 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 1420 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 5137 -> 0 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 2122 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 983 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 10576 -> 0 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 5347 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 1962 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 16284 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 9618 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 3003 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 22725 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 14809 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 4166 -> 0 bytes .../src/main/res/values/colors.xml | 7 - .../src/main/res/values/strings.xml | 3 - .../src/main/res/values/styles.xml | 17 - .../feature/wallet/WalletTest.java | 140 ---- .../example-jv-02threading/build.gradle.kts | 93 --- .../example-jv-02threading/screenshot.png | Bin 31079 -> 0 bytes .../forethreading/ProgressBarIdler.java | 104 --- .../forethreading/ui/CounterViewTest.java | 136 ---- .../forethreading/ui/StateBuilder.java | 69 -- .../src/main/AndroidManifest.xml | 20 - .../foo/bar/example/forethreading/App.java | 26 - .../foo/bar/example/forethreading/OG.java | 79 -- .../feature/counter/CounterWithLambdas.java | 83 -- .../feature/counter/CounterWithProgress.java | 98 --- .../forethreading/ui/CounterActivity.java | 101 --- .../src/main/res/layout/activity_counter.xml | 102 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 7805 -> 0 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 3633 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 1420 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 5137 -> 0 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 2122 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 983 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 10576 -> 0 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 5347 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 1962 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 16284 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 9618 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 3003 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 22725 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 14809 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 4166 -> 0 bytes .../src/main/res/values/colors.xml | 7 - .../src/main/res/values/strings.xml | 3 - .../src/main/res/values/styles.xml | 17 - .../counter/CounterWithLambdasTest.java | 83 -- .../counter/CounterWithProgressTest.java | 125 --- .../example-jv-03adapters/build.gradle.kts | 96 --- .../example-jv-03adapters/screenshot.png | Bin 77226 -> 0 bytes .../foreadapters/ui/EspressoTestMatchers.java | 28 - .../ui/playlist/PlaylistsViewTest.java | 241 ------ .../ui/playlist/StateBuilder.java | 69 -- .../src/main/AndroidManifest.xml | 20 - .../foo/bar/example/foreadapters/App.java | 25 - .../java/foo/bar/example/foreadapters/OG.java | 79 -- .../playlist/ImmutablePlaylistModel.java | 88 -- .../playlist/MutablePlaylistModel.java | 113 --- .../playlist/RandomTrackGeneratorUtil.java | 26 - .../foreadapters/feature/playlist/Track.java | 82 -- .../ui/playlist/PlaylistsActivity.java | 11 - .../playlist/immutable/ImmutableListView.java | 124 --- .../immutable/ImmutablePlaylistAdapter.java | 114 --- .../ui/playlist/mutable/MutableListView.java | 122 --- .../mutable/MutablePlaylistAdapter.java | 113 --- .../foreadapters/ui/widget/PercentPie.java | 121 --- .../main/res/layout/activity_playlists.xml | 19 - .../layout/activity_playlists_listitem.xml | 41 - .../main/res/layout/view_immutable_based.xml | 93 --- .../main/res/layout/view_mutable_based.xml | 93 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 7805 -> 0 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 3633 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 1420 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 5137 -> 0 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 2122 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 983 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 10576 -> 0 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 5347 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 1962 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 16284 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 9618 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 3003 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 22725 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 14809 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 4166 -> 0 bytes .../src/main/res/values/colors.xml | 15 - .../src/main/res/values/strings.xml | 3 - .../src/main/res/values/styles.xml | 16 - .../playlist/ImmutablePlaylistModelTest.java | 194 ----- .../playlist/MutablePlaylistModelTest.java | 309 ------- .../example-jv-04retrofit/build.gradle.kts | 95 --- .../example-jv-04retrofit/screenshot.png | Bin 32352 -> 0 bytes .../example/foreretrofit/DrawableMatcher.java | 74 -- .../foreretrofit/EspressoTestMatchers.java | 27 - .../foreretrofit/ProgressBarIdler.java | 104 --- .../ui/fruit/FruitViewRotationTest.java | 208 ----- .../FruitViewRotationTestStateBuilder.java | 76 -- .../foreretrofit/ui/fruit/FruitViewTest.java | 185 ----- .../ui/fruit/FruitViewTestStateBuilder.java | 54 -- .../src/main/AndroidManifest.xml | 22 - .../foo/bar/example/foreretrofit/App.java | 26 - .../java/foo/bar/example/foreretrofit/OG.java | 96 --- .../api/CustomGlobalErrorHandler.java | 118 --- .../api/CustomGlobalRequestInterceptor.java | 48 -- .../api/CustomRetrofitBuilder.java | 48 -- .../foreretrofit/api/fruits/FruitPojo.java | 32 - .../foreretrofit/api/fruits/FruitService.java | 24 - .../api/fruits/FruitsCustomError.java | 57 -- .../feature/fruit/FruitFetcher.java | 141 ---- .../foreretrofit/message/UserMessage.java | 74 -- .../foreretrofit/ui/fruit/FruitActivity.java | 140 ---- .../ui/widgets/AnimatedTastyRatingBar.java | 111 --- .../res/drawable-xxhdpi/lemon_negative.png | Bin 3931 -> 0 bytes .../res/drawable-xxhdpi/lemon_positive.png | Bin 3510 -> 0 bytes .../src/main/res/layout/activity_fruit.xml | 124 --- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 7805 -> 0 bytes .../mipmap-hdpi/ic_launcher_background.png | Bin 3633 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 1420 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 5137 -> 0 bytes .../mipmap-mdpi/ic_launcher_background.png | Bin 2122 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 983 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 10576 -> 0 bytes .../mipmap-xhdpi/ic_launcher_background.png | Bin 5347 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 1962 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 16284 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_background.png | Bin 9618 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 3003 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 22725 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_background.png | Bin 14809 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 4166 -> 0 bytes .../src/main/res/values/colors.xml | 7 - .../src/main/res/values/strings.xml | 21 - .../src/main/res/values/styles.xml | 11 - .../api/CommonServiceFailures.java | 46 -- .../fruit/FruitFetcherIntegrationTest.java | 207 ----- .../feature/fruit/FruitFetcherUnitTest.java | 166 ---- .../feature/fruit/StateBuilder.java | 60 -- .../src/test/resources/common/empty.json | 0 .../resources/common/error_user_locked.json | 3 - .../common/error_user_not_enabled.json | 3 - .../src/test/resources/common/html.json | 1 - .../src/test/resources/fruit/success.json | 7 - .../example-kt-01reactiveui/build.gradle.kts | 6 +- .../ui/wallet/WalletsActivityTest.kt | 4 +- .../foo/bar/example/forereactiveuikt/App.kt | 4 +- .../foo/bar/example/forereactiveuikt/OG.kt | 3 +- .../forereactiveuikt/feature/wallet/Wallet.kt | 4 +- .../ui/wallet/WalletsActivity.kt | 32 +- .../feature/wallet/WalletTest.kt | 4 +- .../example-kt-02coroutine/build.gradle.kts | 7 +- .../java/foo/bar/example/forecoroutine/OG.kt | 3 +- .../forecoroutine/feature/counter/Counter.kt | 10 +- .../feature/counter/CounterWithProgress.kt | 8 +- .../forecoroutine/ui/CounterActivity.kt | 2 +- .../example-kt-03adapters/build.gradle.kts | 2 +- .../example-kt-04retrofit/build.gradle.kts | 2 +- .../example-kt-07apollo3/build.gradle.kts | 2 +- .../example-kt-08ktor/build.gradle.kts | 11 +- .../ui/fruit/FruitViewRotationTest.kt | 2 +- .../foo/bar/example/forektorkt/App.kt | 0 .../foo/bar/example/forektorkt/OG.kt | 19 +- .../api/CustomGlobalErrorHandler.kt | 15 +- .../api/CustomGlobalRequestInterceptor.kt | 2 +- .../forektorkt/api/CustomKtorBuilder.kt | 29 +- .../forektorkt/api/fruits/FruitService.kt | 6 +- .../api/fruits/FruitsCustomError.kt | 0 .../example/forektorkt/api/fruits/Pojos.kt | 0 .../forektorkt/feature/fruit/FruitFetcher.kt | 19 +- .../forektorkt/message/ErrorMessage.kt | 0 .../forektorkt/ui/fruit/FruitActivity.kt | 6 +- .../ui/widgets/AnimatedTastyRatingBar.kt | 0 .../forektorkt/api/CommonServiceFailures.kt | 2 +- .../fruit/FruitFetcherIntegrationTest.kt | 8 +- .../feature/fruit/FruitFetcherUnitTest.kt | 2 +- .../forektorkt/feature/fruit/StateBuilder.kt | 2 +- .../example-kt-09compose/build.gradle.kts | 2 +- build.gradle.kts | 16 +- .../kotlin/co/early/fore/PublishKmpConfig.kt | 110 +++ .../{java => kotlin}/co/early/fore/Shared.kt | 14 +- .../fore-jv-android-adapters/build.gradle.kts | 61 -- .../co/early/fore/adapters/Adaptable.java | 6 - .../early/fore/adapters/CrossFadeRemover.java | 28 - .../co/early/fore/adapters/Notifyable.java | 7 - .../co/early/fore/adapters/NotifyableImp.java | 71 -- .../fore/adapters/immutable/DeepCopyable.java | 5 - .../adapters/immutable/DiffCalculator.java | 66 -- .../adapters/immutable/DiffComparator.java | 49 -- .../fore/adapters/immutable/DiffSpec.java | 32 - .../fore/adapters/immutable/Diffable.java | 5 - .../adapters/immutable/ImmutableListMgr.java | 172 ---- .../mutable/ChangeAwareArrayList.java | 235 ------ .../mutable/ChangeAwareLinkedList.java | 229 ------ .../adapters/mutable/ChangeAwareList.java | 45 -- .../fore/adapters/mutable/UpdateSpec.java | 37 - .../fore/adapters/mutable/Updateable.java | 5 - fore-jv/fore-jv-android-core/build.gradle.kts | 60 -- .../fore/core/logging/AndroidLogger.java | 60 -- .../fore/core/observer/ObservableImp.java | 160 ---- .../co/early/fore/core/threading/Async.java | 77 -- .../fore/core/threading/AsyncBuilder.java | 84 -- .../fore-jv-android-network/build.gradle.kts | 64 -- .../early/fore/net/apollo/ApolloCaller.java | 12 - .../fore/net/apollo/CallProcessorApollo.java | 141 ---- .../early/fore/net/apollo/ErrorHandler.java | 20 - .../net/retrofit2/CallProcessorRetrofit2.java | 132 --- .../fore/net/retrofit2/ErrorHandler.java | 24 - .../fore/net/retrofit2/Retrofit2Caller.java | 17 - fore-jv/fore-jv-android/build.gradle.kts | 70 -- .../src/main/AndroidManifest.xml | 1 - .../fore/core/observer/ObserverGroupTest.java | 109 --- .../fore/core/observer/ObserverTest.java | 533 ------------ .../fore/core/ui/trigger/TriggerTest.java | 363 --------- .../core/utils/text/BasicTextWrapperTest.java | 150 ---- .../fore/core/utils/text/TextPadderTest.java | 61 -- fore-jv/fore-jv-core/build.gradle.kts | 20 - .../main/java/co/early/fore/core/Affirm.java | 11 - .../java/co/early/fore/core/WorkMode.java | 6 - .../fore/core/callbacks/ContinueCallback.java | 5 - .../fore/core/callbacks/DoThisCallback.java | 5 - .../callbacks/DoThisWithPayloadCallback.java | 5 - .../fore/core/callbacks/FailureCallback.java | 5 - .../callbacks/FailureCallbackWithPayload.java | 5 - .../fore/core/callbacks/SuccessCallback.java | 5 - .../callbacks/SuccessCallbackWithPayload.java | 5 - .../co/early/fore/core/logging/Logger.java | 17 - .../early/fore/core/logging/SystemLogger.java | 77 -- .../early/fore/core/observer/Observable.java | 7 - .../fore/core/observer/ObservableGroup.java | 7 - .../core/observer/ObservableGroupImp.java | 38 - .../co/early/fore/core/observer/Observer.java | 10 - .../testhelpers/CountDownLatchWrapper.java | 47 -- .../fore/core/time/SystemTimeWrapper.java | 15 - .../co/early/fore/core/ui/SyncableView.java | 5 - .../early/fore/core/ui/trigger/Trigger.java | 159 ---- .../core/utils/text/BasicTextWrapper.java | 169 ---- .../fore/core/utils/text/TextPadder.java | 43 - fore-jv/fore-jv-network/build.gradle.kts | 25 - .../co/early/fore/net/InterceptorLogging.java | 208 ----- .../co/early/fore/net/MessageProvider.java | 9 - .../fore/net/NetworkingLogSanitizer.java | 9 - .../InterceptorStubbedService.java | 55 -- .../fore/net/testhelpers/JunitFileIO.java | 44 - .../testhelpers/StubbedServiceDefinition.java | 53 -- .../fore-kt-android-adapters/build.gradle.kts | 56 -- .../src/main/AndroidManifest.xml | 1 - .../java/co/early/fore/adapters/Adaptable.kt | 6 - .../early/fore/adapters/CrossFadeRemover.kt | 26 - .../java/co/early/fore/adapters/Notifyable.kt | 7 - .../fore/adapters/immutable/DeepCopyable.kt | 5 - .../fore/adapters/immutable/DiffCalculator.kt | 66 -- .../fore/adapters/immutable/DiffComparator.kt | 46 -- .../early/fore/adapters/immutable/DiffSpec.kt | 15 - .../early/fore/adapters/immutable/Diffable.kt | 5 - .../fore/adapters/mutable/ChangeAwareList.kt | 42 - .../early/fore/adapters/mutable/UpdateSpec.kt | 38 - .../early/fore/adapters/mutable/Updateable.kt | 5 - .../early/fore/kt/adapters/NotifyableImp.kt | 67 -- .../kt/adapters/immutable/ImmutableListMgr.kt | 142 ---- .../adapters/mutable/ChangeAwareArrayList.kt | 253 ------ .../adapters/mutable/ChangeAwareLinkedList.kt | 253 ------ .../src/main/AndroidManifest.xml | 1 - fore-kt/fore-kt-android-core/build.gradle.kts | 65 -- .../src/main/AndroidManifest.xml | 1 - .../kt/core/delegate/AndroidDebugDelegate.kt | 13 - .../fore/kt/core/logging/AndroidLogger.kt | 139 ---- .../src/main/AndroidManifest.xml | 1 - fore-kt/fore-kt-android/build.gradle.kts | 73 -- .../src/main/AndroidManifest.xml | 1 - fore-kt/fore-kt-core/build.gradle.kts | 27 - .../main/java/co/early/fore/core/Affirm.java | 13 - .../fore/core/callbacks/ContinueCallback.java | 7 - .../fore/core/callbacks/DoThisCallback.java | 7 - .../callbacks/DoThisWithPayloadCallback.java | 7 - .../fore/core/callbacks/FailureCallback.java | 7 - .../callbacks/FailureCallbackWithPayload.java | 7 - .../fore/core/callbacks/SuccessCallback.java | 7 - .../callbacks/SuccessCallbackWithPayload.java | 7 - .../early/fore/core/time/SystemTimeWrapper.kt | 14 - .../fore/core/utils/text/BasicTextWrapper.kt | 155 ---- .../early/fore/core/utils/text/TextPadder.kt | 39 - .../main/java/co/early/fore/kt/core/Either.kt | 58 -- .../main/java/co/early/fore/kt/core/Ext.kt | 4 - .../early/fore/kt/core/callbacks/TypeAlias.kt | 18 - .../early/fore/kt/core/logging/TagInferer.kt | 39 - .../java/co/early/fore/kt/core/time/Time.kt | 44 - .../core/observer/ObservableGroupImpTest.kt | 286 ------- .../kt/core/observer/ObservableImpTest.kt | 212 ----- .../kt/core/ui/trigger/TriggerOnChangeTest.kt | 255 ------ .../kt/core/ui/trigger/TriggerWhenTest.kt | 405 ---------- .../core/utils/text/BasicTextWrapperTest.kt | 124 --- .../fore/kt/core/utils/text/TextPadderTest.kt | 41 - .../build.gradle.kts | 24 - .../build.gradle.kts | 24 - fore-kt/fore-kt-network/build.gradle.kts | 32 - .../early/fore/kt/net/InterceptorLogging.kt | 314 ------- .../kt/net/apollo3/CallProcessorApollo3.kt | 131 --- .../fore/kt/net/apollo3/CallWrapperApollo3.kt | 131 --- .../early/fore/kt/net/apollo3/ErrorHandler.kt | 22 - .../fore/kt/net/ktor/CallProcessorKtor.kt | 129 --- .../net/testhelpers/InterceptorStubOkHttp3.kt | 75 -- .../fore/kt/net/testhelpers/JunitFileIO.kt | 39 - .../co/early/fore/net/InterceptorLogging.kt | 193 ----- .../early/fore/net/NetworkingLogSanitizer.kt | 8 - .../testhelpers/InterceptorStubbedService.kt | 46 -- .../testhelpers/StubbedServiceDefinition.kt | 49 -- gradle.properties | 4 +- gradle/libs.versions.toml | 36 +- gradle/wrapper/gradle-wrapper.properties | 2 +- lib/fore-core/build.gradle.kts | 116 +++ lib/fore-core/fore_core.podspec | 50 ++ .../early/fore/core/logging/Logger.android.kt | 23 + .../fore/core/logging/TagInferer.android.kt | 31 + .../fore/core/observer/ThreadId.android.kt | 5 + .../core/testhelpers/CountDownLatchWrapper.kt | 3 +- .../core/time/SystemTimeWrapper.android.kt | 13 + .../kotlin/co/early/fore}/core/ui/Ext.kt | 3 +- .../fore}/core/ui/ForeLifecycleObserver.kt | 5 +- .../early/fore/core/logging/Logger.apple.kt | 38 + .../kotlin}/co/early/fore/core/WorkMode.kt | 2 +- .../co/early/fore}/core/coroutine/Ext.kt | 33 +- .../co/early/fore}/core/delegate/Delegates.kt | 52 +- .../co/early/fore}/core/logging/Logger.kt | 8 +- .../fore/core/logging/MultiplatformLogger.kt | 158 ++++ .../early/fore}/core/logging/SilentLogger.kt | 2 +- .../early/fore}/core/logging/SystemLogger.kt | 29 +- .../early/fore}/core/logging/TagFormatter.kt | 17 +- .../co/early/fore/core/logging/TagInferer.kt | 7 + .../co/early/fore/core/observer/Observable.kt | 0 .../fore/core/observer/ObservableGroup.kt | 0 .../fore}/core/observer/ObservableGroupImp.kt | 6 +- .../fore}/core/observer/ObservableImp.kt | 102 ++- .../co/early/fore/core/observer/Observer.kt | 0 .../co/early/fore/core/observer/ThreadId.kt | 11 + .../early/fore/core/time/SystemTimeWrapper.kt | 24 + .../kotlin/co/early/fore}/core/type/Either.kt | 6 +- .../co/early/fore/core/ui/SyncableView.kt | 2 +- .../fore}/core/ui/ViewModelObservability.kt | 3 +- .../core/ui/ViewModelObservabilityImp.kt | 21 +- .../early/fore}/core/ui/trigger/ResetRule.kt | 2 +- .../fore}/core/ui/trigger/StateChange.kt | 2 +- .../fore}/core/ui/trigger/TriggerOnChange.kt | 2 +- .../fore}/core/ui/trigger/TriggerWhen.kt | 2 +- .../core/observer/ObservableGroupImpTest.kt | 177 ++++ .../fore/core/observer/ObservableImpTest.kt | 199 +++++ .../core/ui/trigger/TriggerOnChangeTest.kt | 193 +++++ .../fore/core/ui/trigger/TriggerWhenTest.kt | 357 ++++++++ .../early/fore/core/logging/TagInferer.ios.kt | 29 + .../early/fore/core/observer/ThreadId.ios.kt | 7 + .../fore/core/time/SystemTimeWrapper.ios.kt | 29 + .../early/fore/core/logging/JsTagInferer.kt | 30 + .../co/early/fore/core/observer/ThreadId.kt | 9 + .../fore/core/time/JsSystemTimeWrapper.kt | 15 + .../co/early/fore/core/logging/Logger.jvm.kt | 61 ++ .../early/fore/core/logging/TagInferer.jvm.kt | 31 + .../early/fore/core/observer/ThreadId.jvm.kt | 5 + .../fore/core/time/SystemTimeWrapper.jvm.kt | 13 + .../early/fore/core/logging/Logger.linux.kt | 61 ++ .../fore/core/logging/TagInferer.linux.kt | 10 + .../fore/core/observer/ThreadId.linux.kt | 7 + .../fore/core/time/SystemTimeWrapper.linux.kt | 13 + .../fore/core/logging/TagInferer.macos.kt | 30 + .../fore/core/observer/ThreadId.macos.kt | 7 + .../fore/core/time/SystemTimeWrapper.macos.kt | 29 + .../early/fore/core/logging/Logger.mingw.kt | 61 ++ .../fore/core/logging/MingwTagInferer.kt | 10 + .../co/early/fore/core/observer/ThreadId.kt | 7 + .../fore/core/time/MingwSystemTimeWrapper.kt | 69 ++ .../fore/core/logging/TagInferer.tvos.kt | 30 + .../early/fore/core/observer/ThreadId.tvos.kt | 7 + .../fore/core/time/SystemTimeWrapper.tvos.kt | 29 + .../core/logging/TagInferer.watchosArm32.kt | 30 + .../core/observer/ThreadId.watchosArm32.kt | 7 + .../time/SystemTimeWrapper.watchosArm32.kt | 29 + .../core/logging/TagInferer.watchosArm64.kt | 30 + .../core/observer/ThreadId.watchosArm64.kt | 7 + .../time/SystemTimeWrapper.watchosArm64.kt | 29 + .../TagInferer.watchosSimulatorArm64.kt | 30 + .../ThreadId.watchosSimulatorArm64.kt | 7 + ...SystemTimeWrapper.watchosSimulatorArm64.kt | 29 + .../core/logging/TagInferer.watchosX64.kt | 30 + .../fore/core/observer/ThreadId.watchosX64.kt | 7 + .../core/time/SystemTimeWrapper.watchosX64.kt | 29 + .../fore-kt-android-compose/build.gradle.kts | 2 +- .../src/main/AndroidManifest.xml | 0 .../java/co/early/fore/compose/ComposeExt.kt | 0 .../co/early/fore/kt/core/ui/ComposeExt.kt | 0 .../main/java/co/early/fore/ui/size/Ext.kt | 0 .../java/co/early/fore/ui/size/ForeSize.kt | 0 .../co/early/fore/ui/size/SizedComposable.kt | 0 .../java/co/early/fore/ui/size/SizedDp.kt | 0 .../java/co/early/fore/ui/size/SizedFloat.kt | 0 .../java/co/early/fore/ui/size/SizedInt.kt | 0 .../co/early/fore/ui/size/SizedTextUnit.kt | 0 .../java/co/early/fore/ui/size/SizedValue.kt | 0 .../java/co/early/fore/ui/size/WindowSize.kt | 0 .../fore-kt-android-network/build.gradle.kts | 2 +- .../src/main/AndroidManifest.xml | 0 .../fore}/net/apollo/CallProcessorApollo.kt | 0 .../fore}/net/apollo/CallWrapperApollo.kt | 0 .../co/early/fore/net/apollo/ErrorHandler.kt | 0 .../net/retrofit2/CallProcessorRetrofit2.kt | 0 .../net/retrofit2/CallWrapperRetrofit2.kt | 0 .../early/fore/net/retrofit2/ErrorHandler.kt | 0 .../net/retrofit2/Retrofit2ResponseExt.kt | 0 lib/fore-net-okhttp3v3x/build.gradle.kts | 22 + .../src/main/AndroidManifest.xml | 0 .../testhelpers/okhttp3v3x/ResponseBuilder.kt | 4 +- lib/fore-net-okhttp3v4x/build.gradle.kts | 20 + .../testhelpers/okhttp3v4x/ResponseBuilder.kt | 3 +- lib/fore-net/build.gradle.kts | 84 ++ .../kotlin/co/early/fore/net/FileIO.apple.kt | 3 + .../co/early/fore/net/DataHeuristics.kt | 224 +++++ .../kotlin/co/early/fore/net/FileIO.kt | 19 + .../kotlin/co/early/fore/net/HttpLogger.kt | 327 ++++++++ .../co/early/fore/net/InterceptorLogging.kt | 74 ++ .../co/early/fore/net/MessageProvider.kt | 0 .../early/fore/net/NetworkingLogSanitizer.kt | 6 + .../kotlin/co/early/fore/net/PluginLogging.kt | 421 ++++++++++ .../kotlin/co/early/fore/net/Prettifier.kt | 83 ++ .../fore/net/apollo3/CallWrapperApollo3.kt | 131 +++ .../co/early/fore/net/apollo3/ErrorHandler.kt | 22 + .../early/fore}/net/ktor/CallWrapperKtor.kt | 25 +- .../co/early/fore}/net/ktor/ErrorHandler.kt | 2 +- .../co/early/fore/net/DataHeuristicsTest.kt | 261 ++++++ .../co/early/fore/net/PrettifierJsonTest.kt | 153 ++++ .../co/early/fore/net/PrettifierXmlTest.kt | 223 +++++ .../kotlin/co/early/fore/net/FileIO.jvm.kt | 3 + .../co/early/fore/net/InterceptorLogging.kt | 317 ++++++++ .../net/testhelpers/InterceptorStubOkHttp3.kt | 75 ++ .../early/fore/net/testhelpers/JunitFileIO.kt | 39 + .../co/early/fore}/net/testhelpers/Stub.kt | 2 +- lib/fore-net/src/jvmTest/resources/jquery.js | 763 ++++++++++++++++++ lib/fore-net/src/jvmTest/resources/polish.txt | 19 + lib/fore-net/src/jvmTest/resources/test.jpg | Bin 0 -> 1234 bytes .../kotlin/co/early/fore/net/FileIO.linux.kt | 3 + publish-kmp-lib.gradle.kts | 79 ++ publish-lib.gradle.kts | 1 - settings.gradle | 56 +- 462 files changed, 6135 insertions(+), 15583 deletions(-) delete mode 100644 app-examples/example-jv-01reactiveui/build.gradle.kts delete mode 100644 app-examples/example-jv-01reactiveui/screenshot.png delete mode 100644 app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/StateBuilder.java delete mode 100644 app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/WalletsViewTest.java delete mode 100644 app-examples/example-jv-01reactiveui/src/main/AndroidManifest.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/App.java delete mode 100644 app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/OG.java delete mode 100644 app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/feature/wallet/Wallet.java delete mode 100644 app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/ui/wallet/WalletsActivity.java delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/drawable-xxhdpi/moneybag.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/drawable-xxhdpi/phone.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/layout/activity_wallet.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-hdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-mdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/values/colors.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/values/strings.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/main/res/values/styles.xml delete mode 100644 app-examples/example-jv-01reactiveui/src/test/java/foo/bar/example/forereactiveui/feature/wallet/WalletTest.java delete mode 100644 app-examples/example-jv-02threading/build.gradle.kts delete mode 100644 app-examples/example-jv-02threading/screenshot.png delete mode 100644 app-examples/example-jv-02threading/src/androidTest/java/foo/bar/example/forethreading/ProgressBarIdler.java delete mode 100644 app-examples/example-jv-02threading/src/androidTest/java/foo/bar/example/forethreading/ui/CounterViewTest.java delete mode 100644 app-examples/example-jv-02threading/src/androidTest/java/foo/bar/example/forethreading/ui/StateBuilder.java delete mode 100644 app-examples/example-jv-02threading/src/main/AndroidManifest.xml delete mode 100644 app-examples/example-jv-02threading/src/main/java/foo/bar/example/forethreading/App.java delete mode 100644 app-examples/example-jv-02threading/src/main/java/foo/bar/example/forethreading/OG.java delete mode 100644 app-examples/example-jv-02threading/src/main/java/foo/bar/example/forethreading/feature/counter/CounterWithLambdas.java delete mode 100644 app-examples/example-jv-02threading/src/main/java/foo/bar/example/forethreading/feature/counter/CounterWithProgress.java delete mode 100644 app-examples/example-jv-02threading/src/main/java/foo/bar/example/forethreading/ui/CounterActivity.java delete mode 100644 app-examples/example-jv-02threading/src/main/res/layout/activity_counter.xml delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-hdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-mdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-02threading/src/main/res/values/colors.xml delete mode 100644 app-examples/example-jv-02threading/src/main/res/values/strings.xml delete mode 100644 app-examples/example-jv-02threading/src/main/res/values/styles.xml delete mode 100644 app-examples/example-jv-02threading/src/test/java/foo/bar/example/forethreading/feature/counter/CounterWithLambdasTest.java delete mode 100644 app-examples/example-jv-02threading/src/test/java/foo/bar/example/forethreading/feature/counter/CounterWithProgressTest.java delete mode 100644 app-examples/example-jv-03adapters/build.gradle.kts delete mode 100644 app-examples/example-jv-03adapters/screenshot.png delete mode 100644 app-examples/example-jv-03adapters/src/androidTest/java/foo/bar/example/foreadapters/ui/EspressoTestMatchers.java delete mode 100644 app-examples/example-jv-03adapters/src/androidTest/java/foo/bar/example/foreadapters/ui/playlist/PlaylistsViewTest.java delete mode 100644 app-examples/example-jv-03adapters/src/androidTest/java/foo/bar/example/foreadapters/ui/playlist/StateBuilder.java delete mode 100644 app-examples/example-jv-03adapters/src/main/AndroidManifest.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/App.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/OG.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/ImmutablePlaylistModel.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/MutablePlaylistModel.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/RandomTrackGeneratorUtil.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/feature/playlist/Track.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/PlaylistsActivity.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/immutable/ImmutableListView.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/immutable/ImmutablePlaylistAdapter.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/mutable/MutableListView.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/playlist/mutable/MutablePlaylistAdapter.java delete mode 100644 app-examples/example-jv-03adapters/src/main/java/foo/bar/example/foreadapters/ui/widget/PercentPie.java delete mode 100644 app-examples/example-jv-03adapters/src/main/res/layout/activity_playlists.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/layout/activity_playlists_listitem.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/layout/view_immutable_based.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/layout/view_mutable_based.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-hdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-mdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-03adapters/src/main/res/values/colors.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/values/strings.xml delete mode 100644 app-examples/example-jv-03adapters/src/main/res/values/styles.xml delete mode 100644 app-examples/example-jv-03adapters/src/test/java/foo/bar/example/foreadapters/feature/playlist/ImmutablePlaylistModelTest.java delete mode 100644 app-examples/example-jv-03adapters/src/test/java/foo/bar/example/foreadapters/feature/playlist/MutablePlaylistModelTest.java delete mode 100644 app-examples/example-jv-04retrofit/build.gradle.kts delete mode 100644 app-examples/example-jv-04retrofit/screenshot.png delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/DrawableMatcher.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/EspressoTestMatchers.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/ProgressBarIdler.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/ui/fruit/FruitViewRotationTest.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/ui/fruit/FruitViewRotationTestStateBuilder.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/ui/fruit/FruitViewTest.java delete mode 100644 app-examples/example-jv-04retrofit/src/androidTest/java/foo/bar/example/foreretrofit/ui/fruit/FruitViewTestStateBuilder.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/AndroidManifest.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/App.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/OG.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/CustomGlobalErrorHandler.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/CustomGlobalRequestInterceptor.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/CustomRetrofitBuilder.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/fruits/FruitPojo.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/fruits/FruitService.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/api/fruits/FruitsCustomError.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcher.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/message/UserMessage.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/ui/fruit/FruitActivity.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/java/foo/bar/example/foreretrofit/ui/widgets/AnimatedTastyRatingBar.java delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/drawable-xxhdpi/lemon_negative.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/drawable-xxhdpi/lemon_positive.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/layout/activity_fruit.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-hdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-mdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/values/colors.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/values/strings.xml delete mode 100644 app-examples/example-jv-04retrofit/src/main/res/values/styles.xml delete mode 100644 app-examples/example-jv-04retrofit/src/test/java/foo/bar/example/foreretrofit/api/CommonServiceFailures.java delete mode 100644 app-examples/example-jv-04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherIntegrationTest.java delete mode 100644 app-examples/example-jv-04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/FruitFetcherUnitTest.java delete mode 100644 app-examples/example-jv-04retrofit/src/test/java/foo/bar/example/foreretrofit/feature/fruit/StateBuilder.java delete mode 100644 app-examples/example-jv-04retrofit/src/test/resources/common/empty.json delete mode 100644 app-examples/example-jv-04retrofit/src/test/resources/common/error_user_locked.json delete mode 100644 app-examples/example-jv-04retrofit/src/test/resources/common/error_user_not_enabled.json delete mode 100644 app-examples/example-jv-04retrofit/src/test/resources/common/html.json delete mode 100644 app-examples/example-jv-04retrofit/src/test/resources/fruit/success.json rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/App.kt (100%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/OG.kt (80%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/CustomGlobalErrorHandler.kt (87%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/CustomGlobalRequestInterceptor.kt (96%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/CustomKtorBuilder.kt (56%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/fruits/FruitService.kt (88%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/fruits/FruitsCustomError.kt (100%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/api/fruits/Pojos.kt (100%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/feature/fruit/FruitFetcher.kt (92%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/message/ErrorMessage.kt (100%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/ui/fruit/FruitActivity.kt (95%) rename app-examples/example-kt-08ktor/src/main/{java => kotlin}/foo/bar/example/forektorkt/ui/widgets/AnimatedTastyRatingBar.kt (100%) rename app-examples/example-kt-08ktor/src/test/{java => kotlin}/foo/bar/example/forektorkt/api/CommonServiceFailures.kt (97%) rename app-examples/example-kt-08ktor/src/test/{java => kotlin}/foo/bar/example/forektorkt/feature/fruit/FruitFetcherIntegrationTest.kt (97%) rename app-examples/example-kt-08ktor/src/test/{java => kotlin}/foo/bar/example/forektorkt/feature/fruit/FruitFetcherUnitTest.kt (99%) rename app-examples/example-kt-08ktor/src/test/{java => kotlin}/foo/bar/example/forektorkt/feature/fruit/StateBuilder.kt (95%) create mode 100644 buildSrc/src/main/kotlin/co/early/fore/PublishKmpConfig.kt rename buildSrc/src/main/{java => kotlin}/co/early/fore/Shared.kt (91%) delete mode 100644 fore-jv/fore-jv-android-adapters/build.gradle.kts delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/Adaptable.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/CrossFadeRemover.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/Notifyable.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/NotifyableImp.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/DeepCopyable.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffCalculator.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffComparator.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffSpec.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/Diffable.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/immutable/ImmutableListMgr.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/mutable/ChangeAwareArrayList.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/mutable/ChangeAwareLinkedList.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/mutable/ChangeAwareList.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/mutable/UpdateSpec.java delete mode 100644 fore-jv/fore-jv-android-adapters/src/main/java/co/early/fore/adapters/mutable/Updateable.java delete mode 100644 fore-jv/fore-jv-android-core/build.gradle.kts delete mode 100644 fore-jv/fore-jv-android-core/src/main/java/co/early/fore/core/logging/AndroidLogger.java delete mode 100644 fore-jv/fore-jv-android-core/src/main/java/co/early/fore/core/observer/ObservableImp.java delete mode 100644 fore-jv/fore-jv-android-core/src/main/java/co/early/fore/core/threading/Async.java delete mode 100644 fore-jv/fore-jv-android-core/src/main/java/co/early/fore/core/threading/AsyncBuilder.java delete mode 100644 fore-jv/fore-jv-android-network/build.gradle.kts delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/apollo/ApolloCaller.java delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/apollo/CallProcessorApollo.java delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/apollo/ErrorHandler.java delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/retrofit2/CallProcessorRetrofit2.java delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/retrofit2/ErrorHandler.java delete mode 100644 fore-jv/fore-jv-android-network/src/main/java/co/early/fore/net/retrofit2/Retrofit2Caller.java delete mode 100644 fore-jv/fore-jv-android/build.gradle.kts delete mode 100644 fore-jv/fore-jv-android/src/main/AndroidManifest.xml delete mode 100644 fore-jv/fore-jv-android/src/test/java/co/early/fore/core/observer/ObserverGroupTest.java delete mode 100644 fore-jv/fore-jv-android/src/test/java/co/early/fore/core/observer/ObserverTest.java delete mode 100644 fore-jv/fore-jv-android/src/test/java/co/early/fore/core/ui/trigger/TriggerTest.java delete mode 100644 fore-jv/fore-jv-android/src/test/java/co/early/fore/core/utils/text/BasicTextWrapperTest.java delete mode 100644 fore-jv/fore-jv-android/src/test/java/co/early/fore/core/utils/text/TextPadderTest.java delete mode 100644 fore-jv/fore-jv-core/build.gradle.kts delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/Affirm.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/WorkMode.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/ContinueCallback.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/DoThisCallback.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/DoThisWithPayloadCallback.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/FailureCallback.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/FailureCallbackWithPayload.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/SuccessCallback.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/callbacks/SuccessCallbackWithPayload.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/logging/Logger.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/logging/SystemLogger.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/observer/Observable.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/observer/ObservableGroup.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/observer/ObservableGroupImp.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/observer/Observer.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/testhelpers/CountDownLatchWrapper.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/time/SystemTimeWrapper.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/ui/SyncableView.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/ui/trigger/Trigger.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/utils/text/BasicTextWrapper.java delete mode 100644 fore-jv/fore-jv-core/src/main/java/co/early/fore/core/utils/text/TextPadder.java delete mode 100644 fore-jv/fore-jv-network/build.gradle.kts delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/InterceptorLogging.java delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/MessageProvider.java delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/NetworkingLogSanitizer.java delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/testhelpers/InterceptorStubbedService.java delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/testhelpers/JunitFileIO.java delete mode 100644 fore-jv/fore-jv-network/src/main/java/co/early/fore/net/testhelpers/StubbedServiceDefinition.java delete mode 100644 fore-kt/fore-kt-android-adapters/build.gradle.kts delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/AndroidManifest.xml delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/Adaptable.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/CrossFadeRemover.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/Notifyable.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/immutable/DeepCopyable.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffCalculator.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffComparator.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/immutable/DiffSpec.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/immutable/Diffable.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/mutable/ChangeAwareList.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/mutable/UpdateSpec.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/adapters/mutable/Updateable.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/kt/adapters/NotifyableImp.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/kt/adapters/immutable/ImmutableListMgr.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/kt/adapters/mutable/ChangeAwareArrayList.kt delete mode 100644 fore-kt/fore-kt-android-adapters/src/main/java/co/early/fore/kt/adapters/mutable/ChangeAwareLinkedList.kt delete mode 100644 fore-kt/fore-kt-android-compose/src/main/AndroidManifest.xml delete mode 100644 fore-kt/fore-kt-android-core/build.gradle.kts delete mode 100644 fore-kt/fore-kt-android-core/src/main/AndroidManifest.xml delete mode 100644 fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt/core/delegate/AndroidDebugDelegate.kt delete mode 100644 fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt/core/logging/AndroidLogger.kt delete mode 100644 fore-kt/fore-kt-android-network/src/main/AndroidManifest.xml delete mode 100644 fore-kt/fore-kt-android/build.gradle.kts delete mode 100644 fore-kt/fore-kt-android/src/main/AndroidManifest.xml delete mode 100644 fore-kt/fore-kt-core/build.gradle.kts delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/Affirm.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/ContinueCallback.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/DoThisCallback.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/DoThisWithPayloadCallback.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/FailureCallback.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/FailureCallbackWithPayload.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/SuccessCallback.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/callbacks/SuccessCallbackWithPayload.java delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/time/SystemTimeWrapper.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/utils/text/BasicTextWrapper.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/core/utils/text/TextPadder.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/kt/core/Either.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/kt/core/Ext.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/kt/core/callbacks/TypeAlias.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/kt/core/logging/TagInferer.kt delete mode 100644 fore-kt/fore-kt-core/src/main/java/co/early/fore/kt/core/time/Time.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/observer/ObservableGroupImpTest.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/observer/ObservableImpTest.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/ui/trigger/TriggerOnChangeTest.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/ui/trigger/TriggerWhenTest.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/utils/text/BasicTextWrapperTest.kt delete mode 100644 fore-kt/fore-kt-core/src/test/java/co/early/fore/kt/core/utils/text/TextPadderTest.kt delete mode 100644 fore-kt/fore-kt-network-okhttp3v3x/build.gradle.kts delete mode 100644 fore-kt/fore-kt-network-okhttp3v4x/build.gradle.kts delete mode 100644 fore-kt/fore-kt-network/build.gradle.kts delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/InterceptorLogging.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/apollo3/CallProcessorApollo3.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/apollo3/CallWrapperApollo3.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/apollo3/ErrorHandler.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/ktor/CallProcessorKtor.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/testhelpers/InterceptorStubOkHttp3.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/kt/net/testhelpers/JunitFileIO.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/net/InterceptorLogging.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/net/NetworkingLogSanitizer.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/net/testhelpers/InterceptorStubbedService.kt delete mode 100644 fore-kt/fore-kt-network/src/main/java/co/early/fore/net/testhelpers/StubbedServiceDefinition.kt create mode 100644 lib/fore-core/build.gradle.kts create mode 100644 lib/fore-core/fore_core.podspec create mode 100644 lib/fore-core/src/androidMain/kotlin/co/early/fore/core/logging/Logger.android.kt create mode 100644 lib/fore-core/src/androidMain/kotlin/co/early/fore/core/logging/TagInferer.android.kt create mode 100644 lib/fore-core/src/androidMain/kotlin/co/early/fore/core/observer/ThreadId.android.kt rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/androidMain/kotlin}/co/early/fore/core/testhelpers/CountDownLatchWrapper.kt (94%) create mode 100644 lib/fore-core/src/androidMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.android.kt rename {fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt => lib/fore-core/src/androidMain/kotlin/co/early/fore}/core/ui/Ext.kt (87%) rename {fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt => lib/fore-core/src/androidMain/kotlin/co/early/fore}/core/ui/ForeLifecycleObserver.kt (89%) create mode 100644 lib/fore-core/src/appleMain/kotlin/co/early/fore/core/logging/Logger.apple.kt rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/commonMain/kotlin}/co/early/fore/core/WorkMode.kt (97%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/coroutine/Ext.kt (91%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/delegate/Delegates.kt (71%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/logging/Logger.kt (67%) create mode 100644 lib/fore-core/src/commonMain/kotlin/co/early/fore/core/logging/MultiplatformLogger.kt rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/logging/SilentLogger.kt (96%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/logging/SystemLogger.kt (74%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/logging/TagFormatter.kt (58%) create mode 100644 lib/fore-core/src/commonMain/kotlin/co/early/fore/core/logging/TagInferer.kt rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/commonMain/kotlin}/co/early/fore/core/observer/Observable.kt (100%) rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/commonMain/kotlin}/co/early/fore/core/observer/ObservableGroup.kt (100%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/observer/ObservableGroupImp.kt (79%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/observer/ObservableImp.kt (59%) rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/commonMain/kotlin}/co/early/fore/core/observer/Observer.kt (100%) create mode 100644 lib/fore-core/src/commonMain/kotlin/co/early/fore/core/observer/ThreadId.kt create mode 100644 lib/fore-core/src/commonMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.kt rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/type/Either.kt (80%) rename {fore-kt/fore-kt-core/src/main/java => lib/fore-core/src/commonMain/kotlin}/co/early/fore/core/ui/SyncableView.kt (97%) rename {fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/ViewModelObservability.kt (66%) rename {fore-kt/fore-kt-android-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/ViewModelObservabilityImp.kt (76%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/trigger/ResetRule.kt (94%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/trigger/StateChange.kt (83%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/trigger/TriggerOnChange.kt (98%) rename {fore-kt/fore-kt-core/src/main/java/co/early/fore/kt => lib/fore-core/src/commonMain/kotlin/co/early/fore}/core/ui/trigger/TriggerWhen.kt (98%) create mode 100644 lib/fore-core/src/commonTest/kotlin/co/early/fore/core/observer/ObservableGroupImpTest.kt create mode 100644 lib/fore-core/src/commonTest/kotlin/co/early/fore/core/observer/ObservableImpTest.kt create mode 100644 lib/fore-core/src/commonTest/kotlin/co/early/fore/core/ui/trigger/TriggerOnChangeTest.kt create mode 100644 lib/fore-core/src/commonTest/kotlin/co/early/fore/core/ui/trigger/TriggerWhenTest.kt create mode 100644 lib/fore-core/src/iosMain/kotlin/co/early/fore/core/logging/TagInferer.ios.kt create mode 100644 lib/fore-core/src/iosMain/kotlin/co/early/fore/core/observer/ThreadId.ios.kt create mode 100644 lib/fore-core/src/iosMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.ios.kt create mode 100644 lib/fore-core/src/jsMain/kotlin/co/early/fore/core/logging/JsTagInferer.kt create mode 100644 lib/fore-core/src/jsMain/kotlin/co/early/fore/core/observer/ThreadId.kt create mode 100644 lib/fore-core/src/jsMain/kotlin/co/early/fore/core/time/JsSystemTimeWrapper.kt create mode 100644 lib/fore-core/src/jvmMain/kotlin/co/early/fore/core/logging/Logger.jvm.kt create mode 100644 lib/fore-core/src/jvmMain/kotlin/co/early/fore/core/logging/TagInferer.jvm.kt create mode 100644 lib/fore-core/src/jvmMain/kotlin/co/early/fore/core/observer/ThreadId.jvm.kt create mode 100644 lib/fore-core/src/jvmMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.jvm.kt create mode 100644 lib/fore-core/src/linuxMain/kotlin/co/early/fore/core/logging/Logger.linux.kt create mode 100644 lib/fore-core/src/linuxMain/kotlin/co/early/fore/core/logging/TagInferer.linux.kt create mode 100644 lib/fore-core/src/linuxMain/kotlin/co/early/fore/core/observer/ThreadId.linux.kt create mode 100644 lib/fore-core/src/linuxMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.linux.kt create mode 100644 lib/fore-core/src/macosMain/kotlin/co/early/fore/core/logging/TagInferer.macos.kt create mode 100644 lib/fore-core/src/macosMain/kotlin/co/early/fore/core/observer/ThreadId.macos.kt create mode 100644 lib/fore-core/src/macosMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.macos.kt create mode 100644 lib/fore-core/src/mingwMain/kotlin/co/early/fore/core/logging/Logger.mingw.kt create mode 100644 lib/fore-core/src/mingwMain/kotlin/co/early/fore/core/logging/MingwTagInferer.kt create mode 100644 lib/fore-core/src/mingwMain/kotlin/co/early/fore/core/observer/ThreadId.kt create mode 100644 lib/fore-core/src/mingwMain/kotlin/co/early/fore/core/time/MingwSystemTimeWrapper.kt create mode 100644 lib/fore-core/src/tvosMain/kotlin/co/early/fore/core/logging/TagInferer.tvos.kt create mode 100644 lib/fore-core/src/tvosMain/kotlin/co/early/fore/core/observer/ThreadId.tvos.kt create mode 100644 lib/fore-core/src/tvosMain/kotlin/co/early/fore/core/time/SystemTimeWrapper.tvos.kt create mode 100644 lib/fore-core/src/watchosArm32Main/kotlin/co/early/fore/core/logging/TagInferer.watchosArm32.kt create mode 100644 lib/fore-core/src/watchosArm32Main/kotlin/co/early/fore/core/observer/ThreadId.watchosArm32.kt create mode 100644 lib/fore-core/src/watchosArm32Main/kotlin/co/early/fore/core/time/SystemTimeWrapper.watchosArm32.kt create mode 100644 lib/fore-core/src/watchosArm64Main/kotlin/co/early/fore/core/logging/TagInferer.watchosArm64.kt create mode 100644 lib/fore-core/src/watchosArm64Main/kotlin/co/early/fore/core/observer/ThreadId.watchosArm64.kt create mode 100644 lib/fore-core/src/watchosArm64Main/kotlin/co/early/fore/core/time/SystemTimeWrapper.watchosArm64.kt create mode 100644 lib/fore-core/src/watchosSimulatorArm64Main/kotlin/co/early/fore/core/logging/TagInferer.watchosSimulatorArm64.kt create mode 100644 lib/fore-core/src/watchosSimulatorArm64Main/kotlin/co/early/fore/core/observer/ThreadId.watchosSimulatorArm64.kt create mode 100644 lib/fore-core/src/watchosSimulatorArm64Main/kotlin/co/early/fore/core/time/SystemTimeWrapper.watchosSimulatorArm64.kt create mode 100644 lib/fore-core/src/watchosX64Main/kotlin/co/early/fore/core/logging/TagInferer.watchosX64.kt create mode 100644 lib/fore-core/src/watchosX64Main/kotlin/co/early/fore/core/observer/ThreadId.watchosX64.kt create mode 100644 lib/fore-core/src/watchosX64Main/kotlin/co/early/fore/core/time/SystemTimeWrapper.watchosX64.kt rename {fore-kt => lib}/fore-kt-android-compose/build.gradle.kts (96%) rename {fore-jv/fore-jv-android-adapters => lib/fore-kt-android-compose}/src/main/AndroidManifest.xml (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/compose/ComposeExt.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/kt/core/ui/ComposeExt.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/Ext.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/ForeSize.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedComposable.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedDp.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedFloat.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedInt.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedTextUnit.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/SizedValue.kt (100%) rename {fore-kt => lib}/fore-kt-android-compose/src/main/java/co/early/fore/ui/size/WindowSize.kt (100%) rename {fore-kt => lib}/fore-kt-android-network/build.gradle.kts (96%) rename {fore-jv/fore-jv-android-core => lib/fore-kt-android-network}/src/main/AndroidManifest.xml (100%) rename {fore-kt/fore-kt-android-network/src/main/java/co/early/fore/kt => lib/fore-kt-android-network/src/main/java/co/early/fore}/net/apollo/CallProcessorApollo.kt (100%) rename {fore-kt/fore-kt-android-network/src/main/java/co/early/fore/kt => lib/fore-kt-android-network/src/main/java/co/early/fore}/net/apollo/CallWrapperApollo.kt (100%) rename {fore-kt => lib}/fore-kt-android-network/src/main/java/co/early/fore/net/apollo/ErrorHandler.kt (100%) rename {fore-kt/fore-kt-android-network/src/main/java/co/early/fore/kt => lib/fore-kt-android-network/src/main/java/co/early/fore}/net/retrofit2/CallProcessorRetrofit2.kt (100%) rename {fore-kt/fore-kt-android-network/src/main/java/co/early/fore/kt => lib/fore-kt-android-network/src/main/java/co/early/fore}/net/retrofit2/CallWrapperRetrofit2.kt (100%) rename {fore-kt => lib}/fore-kt-android-network/src/main/java/co/early/fore/net/retrofit2/ErrorHandler.kt (100%) rename {fore-kt/fore-kt-android-network/src/main/java/co/early/fore/kt => lib/fore-kt-android-network/src/main/java/co/early/fore}/net/retrofit2/Retrofit2ResponseExt.kt (100%) create mode 100644 lib/fore-net-okhttp3v3x/build.gradle.kts rename {fore-jv/fore-jv-android-network => lib/fore-net-okhttp3v3x}/src/main/AndroidManifest.xml (100%) rename {fore-kt/fore-kt-network-okhttp3v3x/src/main/java/co/early/fore/kt => lib/fore-net-okhttp3v3x/src/main/kotlin/co/early/fore}/net/testhelpers/okhttp3v3x/ResponseBuilder.kt (91%) create mode 100644 lib/fore-net-okhttp3v4x/build.gradle.kts rename {fore-kt/fore-kt-network-okhttp3v4x/src/main/java/co/early/fore/kt => lib/fore-net-okhttp3v4x/src/main/kotlin/co/early/fore}/net/testhelpers/okhttp3v4x/ResponseBuilder.kt (91%) create mode 100644 lib/fore-net/build.gradle.kts create mode 100644 lib/fore-net/src/appleMain/kotlin/co/early/fore/net/FileIO.apple.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/DataHeuristics.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/FileIO.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/HttpLogger.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/InterceptorLogging.kt rename {fore-kt/fore-kt-network/src/main/java => lib/fore-net/src/commonMain/kotlin}/co/early/fore/net/MessageProvider.kt (100%) create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/NetworkingLogSanitizer.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/PluginLogging.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/Prettifier.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/apollo3/CallWrapperApollo3.kt create mode 100644 lib/fore-net/src/commonMain/kotlin/co/early/fore/net/apollo3/ErrorHandler.kt rename {fore-kt/fore-kt-network/src/main/java/co/early/fore/kt => lib/fore-net/src/commonMain/kotlin/co/early/fore}/net/ktor/CallWrapperKtor.kt (86%) rename {fore-kt/fore-kt-network/src/main/java/co/early/fore/kt => lib/fore-net/src/commonMain/kotlin/co/early/fore}/net/ktor/ErrorHandler.kt (94%) create mode 100644 lib/fore-net/src/commonTest/kotlin/co/early/fore/net/DataHeuristicsTest.kt create mode 100644 lib/fore-net/src/commonTest/kotlin/co/early/fore/net/PrettifierJsonTest.kt create mode 100644 lib/fore-net/src/commonTest/kotlin/co/early/fore/net/PrettifierXmlTest.kt create mode 100644 lib/fore-net/src/jvmMain/kotlin/co/early/fore/net/FileIO.jvm.kt create mode 100644 lib/fore-net/src/jvmMain/kotlin/co/early/fore/net/InterceptorLogging.kt create mode 100644 lib/fore-net/src/jvmMain/kotlin/co/early/fore/net/testhelpers/InterceptorStubOkHttp3.kt create mode 100644 lib/fore-net/src/jvmMain/kotlin/co/early/fore/net/testhelpers/JunitFileIO.kt rename {fore-kt/fore-kt-network/src/main/java/co/early/fore/kt => lib/fore-net/src/jvmMain/kotlin/co/early/fore}/net/testhelpers/Stub.kt (98%) create mode 100644 lib/fore-net/src/jvmTest/resources/jquery.js create mode 100644 lib/fore-net/src/jvmTest/resources/polish.txt create mode 100644 lib/fore-net/src/jvmTest/resources/test.jpg create mode 100644 lib/fore-net/src/linuxMain/kotlin/co/early/fore/net/FileIO.linux.kt create mode 100644 publish-kmp-lib.gradle.kts diff --git a/.gitignore b/.gitignore index 3bf8bd1a..242ab3b4 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,6 @@ secret_key_ring.gpg # passwords secrets.properties + +# Ignore Kotlin/Native metadata and build artifacts +.kotlin/ diff --git a/app-examples/example-jv-01reactiveui/build.gradle.kts b/app-examples/example-jv-01reactiveui/build.gradle.kts deleted file mode 100644 index 8804ac49..00000000 --- a/app-examples/example-jv-01reactiveui/build.gradle.kts +++ /dev/null @@ -1,92 +0,0 @@ -import co.early.fore.Shared -import co.early.fore.Shared.BuildTypes - -plugins { - alias(libs.plugins.androidApplication) -} - -val appId = "foo.bar.example.forereactiveui" - -fun getTestBuildType(): String { - return project.properties["testBuildType"] as String? ?: BuildTypes.DEFAULT -} - -println("[$appId testBuildType:${getTestBuildType()}]") - -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(Shared.Versions.jvm_toolchain)) - } -} - -android { - - namespace = appId - compileSdk = Shared.Android.compileSdk - - defaultConfig { - applicationId = appId - minSdk = Shared.Android.minSdk - targetSdk = Shared.Android.targetSdk - versionCode = 1 - versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - testBuildType = getTestBuildType() - } - signingConfigs { - create(BuildTypes.RELEASE) { - // keytool -genkey -v -keystore debug.fake_keystore -storetype PKCS12 -alias android -storepass android -keypass android -keyalg RSA -keysize 2048 -validity 20000 -dname "cn=Unknown, ou=Unknown, o=Unknown, c=Unknown" - storeFile = file("../keystore/debug.fake_keystore") - storePassword = "android" - keyAlias = "android" - keyPassword = "android" - } - } - buildTypes { - getByName(BuildTypes.DEBUG) { - isMinifyEnabled = false - } - getByName(BuildTypes.RELEASE) { - isMinifyEnabled = true - proguardFiles(getDefaultProguardFile("proguard-android.txt"), "../proguard-example-app.pro") - signingConfig = signingConfigs.getByName(BuildTypes.RELEASE) - } - } - lint { - abortOnError = true - lintConfig = File(project.rootDir, "lint-example-apps.xml") - } - buildFeatures { - buildConfig = true - } -} - -dependencies { - - if (Shared.Publish.use_published_version) { - implementation("co.early.fore:fore-jv-android-core:${Shared.Publish.published_fore_version_for_examples}") - } else { - implementation(project(":fore-jv:fore-jv-android-core")) - } - - annotationProcessor("com.jakewharton:butterknife-compiler:${Shared.Versions.butterknife}") - //noinspection AnnotationProcessorOnCompilePath - implementation("com.jakewharton:butterknife:${Shared.Versions.butterknife}") - - implementation("androidx.appcompat:appcompat:${Shared.Versions.appcompat}") - implementation("androidx.constraintlayout:constraintlayout:${Shared.Versions.constraintlayout}") - - testImplementation("junit:junit:${Shared.Versions.junit}") - testImplementation("org.mockito:mockito-core:${Shared.Versions.mockito_core}") - testImplementation("org.hamcrest:hamcrest-library:${Shared.Versions.hamcrest_library}") - - androidTestImplementation("org.mockito:mockito-core:${Shared.Versions.mockito_core}") - androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:${Shared.Versions.dexmaker_mockito}") - androidTestImplementation("androidx.test:runner:${Shared.Versions.androidxtest}") - androidTestImplementation("androidx.test:rules:${Shared.Versions.androidxtest}") - androidTestImplementation("androidx.annotation:annotation:${Shared.Versions.annotation}") - androidTestImplementation("androidx.core:core:${Shared.Versions.android_core}") - androidTestImplementation("androidx.test.espresso:espresso-core:${Shared.Versions.espresso_core}") { - exclude(group = "com.android.support", module = "support-annotations") - } -} diff --git a/app-examples/example-jv-01reactiveui/screenshot.png b/app-examples/example-jv-01reactiveui/screenshot.png deleted file mode 100644 index d8b1f112091200e43b67844c2bf3bdd651350915..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23237 zcmb@uWmKF|(=FJzySoQ>4c1tKOK^90cXxsYhu|9A-61$ZgS$J8yG-Yu`R+G=X4YNz z-qoxB)N{I@I(_Qw+O_LE9i^loiGoOo2mk<3q@^U30RV^u0043r9ujO}?GBL!01(Bk z#Ko1Q#l^`TogK`rY|Q`w&y{Qy56z?pT;a_JGcf;tBETpV z9aCg5ED}*28wVpxO6_;>Jfc)~GtVbGw0f0*=FHe8hTHq^0 zjROD@;5g4hjXAvi5z?;oNdrLs1F%Jjd58p&pbQvcQ60esjNk)mRT@kY0m%S>t(UJD zC7>JyaCR##3uGjI%Rm4X2Dj;H)d zlbz+nZcUjc^tis<+M(F#x2+R1!lOqwN7$pxO8ZHLC3OfTH;D`Y5I)WHz4HMR4iEOW z56lm3LAQei?>3hXl)@BOo9~@5kk9~hg(=XA!T$aNl;bc&ty_;xnGRq@9bmcnq{q36 zkf)6}?fn$(#rG;gnv<_IB1l4vh=g=bW1Qc`wi_+{!MW|Q743fyzWToEeF<>N6v?RS zEev^cGO~BCR*pLyhZbYEe>kLi9}Ww6i=&^};i}VR!ufus8P%#pDL?Ghru;*KVl-t3 z^EiOxiY)aFA;|*;P#Lb+tI!PBG;Z7Le*pm*jjB284iNFbVU8h0`T;<<;NtLl005GD zp5jFqApn2Uigp2j&Le!?U&(lKL+}8AL|za>ttcFFA9iIgYE~afXD=S45v+s=GIg&Y zx)|(UATeS-eyS*eYA^p1bW<%9VID^2HhNmPbjRM*VT*q>u{MV=E@ zN60z8zkctOWKRyN{|5CJ(oLl87a8IAp*)uvS1vTYz|;bp8Nx5y%uc#!N?ssgaT^iqGU`NZZqIMba5_+SVms?w?Ab$f8om``E#|U?eg4}SXCm* zu(;eZY5x4g6(28RE}Wmvw6d^zuw*@UZAVxSA^nmzoi=N81b2LR9CGV{j1rC#GAw0G zM_@zXLr{v}Lcp3KR{}GamNBBrw#Y%0VUdoO?x3d0aL?e2^J5G%g+E0-#Xse+Tvg3Q z4LI*rj-*=bG3(o3Lr%X2K^2R##PiJ!OFfT;ztUhuo;x6UpmF7Rp zvk#p9K%frQZC!p|&XSp=m_(WMVTNJ`GS@9wSD9D&SMjcRuXL{%pF5x9o}aFO+#It- zvYE2)`0e-~+z{G%+P}4jwXeEOoe0mFoO&H2+>PC#9dHYP`oa@BI2-8~SQswAb+~@f$n;fI=<<8aD*s$U+ zS%WgsJki6cE2+NYFsbsX50&Za!s=e?cj}9k(hIt$Os94W8n#MA8b6VL^8Xxf{#Es} z>bLt(yG`sJ?0EWF`a2c-751~&GsLsZGuZRb_eS?L_jdPFBooA#Bntwr0=~|!ZWHdd zj-97P+gt->zsm-WH7tlM@?ElTxbaG46UH&q+|%$>>`K3v+UI(Yr|c76w9hup-4*`q z__Iwmi|i@sbWLc zr-FoqC)5c?2aL4-jKP&QCx&>7IhaNIDlFdeY0$ig^c$OtG}WX?$ry?EC| zPbQpe7EGBlIAieHINC(dY!jd4NEa~T!l&Rj(fu7tp5%@vn&Bh2ByA&G$*c%6@Sgmz z=@~f6Sx&w+s<=A2J}@m*?rFVPbj4l8m&LRRtXelayIWLR+bY|doc(MKY%OmM@{D-= za+QYZibaiZ9<}#->9pJvjnBtf2g4lv@buFzjf{6#&>M8ep>jHk_&z9keU)_c{ z5fqgfy?ziRwo%>4t4l0wR8B2BEi->k&PvWIR7SB%ZDd?zYoTjVG-qT?LfP{=up1*v ziWqy?qk3|=S;esplbb1QRIXM+#g$|I#ptPnujAP&)g`6r6CPu3qQ!6yAGh2k4Efzg1PVbT5BeS?F2!@VP+^A;A&Y041MwHZgi?*mQmIyR)CY z2wsmTG$v~AIq+X^mGn>?%!&6Y_JOFKFQuv6xVC6(fL-2WNqu=4Xf z)1%2zn*p_7bia>wv&7eDSLrB!a$s%X&t^tI%N_iwlo#VHe~()wbD>?HP<|KaD5fx* zM4v>myXC_l#J+3dHq0Hbk&~BACv^3+7o43B=|V7yAxB3mU?EhOph__i%oqvLRD_Aq{~Az1BtD}O35 z1DXqXw(gyGS$te%(aZJf0u7xJwb*}JCvK%_zk77QKgaVxypUVd^N#nddF@_#JAr#f zI|*ofuQThl+j=zYHJlpILIa^9MC80Df6PT}&q_{6&QpD*ijB`EBO^i~?7B9cOxiB3 zFU6V~^H=}yI(4Zy+u|j0`T$gmDg38 z1hybJN@=+O07zK>-VlJyEPSvL&Q)6e3*0s$DGmfC(VY+2L=KRa5LNYDIm`C&B%Xh2 z&gJCPDV{IqjZtpK7~&qPNm5;4=9zT&b>CZx&4Bd4c3xZRMoT>Y1dMF_fBI27T} zKy(gWwk2o-@njic^x#-gIwp=#H8U+XtZ6POgn>Z&GZ;JiFiq(4mb5IEBYuJJukm4K zWQ`pte)Re0+R9d12@5Q?V7}1Bh_M;Qr9ozx#)d`0E(PSvf?^`4DLQ*N#WyIU+F{SS z6!JaQjLCp@;O`ebTl!usdpSkB?db2eqKpVf5|*orHZW6|jic@x3DiXzVDBZYzhN`q z0g$Px#hqk#6!nNO&d%na$IpXMDDf1o3VaLKgyKjC+tF<3wiJg%k-r!0%cc_t}gP8#treF@5IL-}>F!tAb)Saks zsZ(_T8qj_RMHCie^t3?>$a>rz)kkRJ+WX_X;NG_N0r{Zwn;}qTd%U1uNCht~^gKv; zYDg`87@Ab zS50-FVF(L@@F&TwOinvwA&T|5=Z>6 z7jrNEl+5_3N3g+Fo?9jFD~Hp&PFHtOmPbdNPWP`6;jKo7e?7B2a7rfnU?M08rBN-5 z^RS5(VhAHZO#N@X{pZIwA&8RO`HOXC%>MqcVh~4!2r@+hO-Zl$C*>xzfVZg9Ak8 zhHrpGr52qIlhWC1WNrBl$tUyznQg89JYnOJ#2$oSFdIrLK2g<9742O~)Bmb=3ZzA$8aAGQ=He}|9jN{)BC~x@ z%jU*XbkdcJ_|@vfb}5A85nbv62_P0eEQ6WayAT)wgpD3hGFAOST?9 z@b|hgP75=&Tlc>5 zWl8%1pD6q0Kx!IJl2&#z|1u9w=oNb~JzhfL?_1=)N0C6kl}@fLAC6 z*d5w{CML);@?PIE{qCW$)QGtFQTy^Mn+vJO$62ExJvx4H7bLQHHEVEny{q?gvR@v} z`D4GAEZJfCL&{M zYJ4G<>>z445Aef?-ny`0H=6{kXDT~J6w)xwSS(A(5c|RU`;s6-$=|ge_*j<9cE9bB zZFN@U9c#Xm+ILl^6^wPU<~f=U=hgtDO36Z%J^h6G`{D{$Ks7^SXb*Cl_o?#fanUuy zMa$`KfOk)*4L`d}n7@WZ_TBh(bUW<73qyeEz*{0)U6?uOdvagB7Rcxih;cEd+2OjQ z0IY}!p(Z>&1Z|0?~QY)gKfS&==l>IA)$(pWwU3^E%Ht z1g}WrK1lVSPsux&NCy<{dqa2!es=pr6l-FeLt1sOC#(k-Ivxx@E+5maMn-WuKF2$r zd33PuP7!zpX8V$6*$ZCU03Jccs-WH{4GJNs4-ZAq%l6f#;!1gqpFj<~gb8ogH_~&+<6pO)+7O{Dt(h>}punqKWSWV^P zMXi;i3w$vc+SAK1YqR6bBm#uhCH=_W+)M;^!qUD0a^LV6fxU|MzYRWOk>Vx9Q4}79 zSz2K~{0Y?d`9O!BM<}mnjige#=W8TC4XMB;2>=;?%W;S{3%*znLx~i+KYK}M{A4GLid^)_uv>fx{m!zy-0yci6c(cWWvForcT)`I%u6g3c2 z5$GXc^848M%O5l2s!m}elM8>WH>99Ph8ku#wkD(idq)JGkyTT6pOLoi3+jnmgu|ma zzo`U~8AMn@2Rw5Z!RQS?uqvAGCt2iI!Eg&CaXjAwTOZo@z-Sm@PyPoE5byydY|AP{ z6xUskWy0Hy35|^M;Y~U(Pl%`I^yD>+;YvHEi?=(0dAn z{a1sI3F5c0<_*31pNR47v#JSV!ArvGH(_Ly5^fRI#FU6&jK?=5bVzl|W5Uu7pJ@i@ z4Nt=1+}KWIXl+HCtEUJd zWw9s(PBy=u_l@Gy$30-{jm+zbFo19SMX8tDqOh~*VSiYjXse>wc4z9VxO_a|PyhQS zY@j4au0*Uo=&aLpmlm`2N^I>$(D_=RoKY{14x#c5ne#wYhA%6f3k%DFl9mjWc12sM zos{NuS`%p?C^Osg*LlrK9`*a>nf=mOHO(@V`KziW zG{u&y(Xcvv5XOt)srT9wb-BmR@FtkEq!C@=$MNCF82zc=YfG!t1=Lc<@xjcn2^*|T zc?p`NbtXJ7vTZpUj}x}8)lTebF?Zm3*hmP!0dl<9p0X8xh8*8GK5%vj#hHA|62?QN z)wR#^z=yt^;CO6s_YuM)4sSN+%kn%B6?EcdX~QUeb4;Ki1u(~sOf1LVO2R`!Y4$*J z9`x-?ce4wSp>@T{S4?XHdy$b1U;%$MpnA&{l~jU6I4S!~t=eu(v3-D7PcK-h%9j?q z_rq7KjNp{g4%~4F=r!ZrO_jY$I%T(jxOkes*zdg0;OJQ4KT=V!&<*8eIdL()_mCOw zr3G#A0{i6Apdf)j5&@YP-BwH2QpK!@)N1V+l+GsZr`E;LUM{Cw%D<}Q#Am-wJ#zYN z@M?$U`z*+A3y3JtQA{id;skL@4VLzcvmj%#W2h7dGR-`%z9rk8IVeXex4t=~^Lspm z+f#;15Qk$iqgYz?M%GQ=2{);=Q?&J=(!Ot!VIUaYl}Z~8Qj$D3!~GnNesPcxcT?W6 zM^g}l+Z2Wn29i5&|FA5V{E7?E{h)=`-o7c!hs7hE*Vyh~Dt?i2YT$;5R0{km-V5m54+o>;ZR-mKoYE#D7|OrG>T_uh*tb?v=p6}460Nr z&|_SsBqIiEHPfkY+tZUB@#}?tJ}u_Z8}H6{9f5l72&9IC-5a!-*)<0z{?u2*AlxI^ zi*8sCV2Hs+NJmXrB0eXAfNWAn>}qzSFK`cMH;xueb6P)eOb>R(zVMwx>bme;1Q2`< z>#(~VZE$*5qa#F#$9oWr$jtUUZ0d8Jo^82Wa2Xwz%=s>^c%+O(Mh@EoP7&xg(uR6-mv{$I+lUq3I^x6dV(@77X4@6?$dSCLJrrdNIma0x8+*hpos=@B;|6&>6>#E``z_+-RUyQYT>m-7U@ z=!-^kdbzZEX@Mp<-=IPINUI-!sQ7^p?H@YFy4EF@j{d7=h-P?qhGt}JU`inby>*96 z@NNd+Le*iUWoa|?6tV39>N~#RBLkk2SH1$SBm$ZSHL-8vdx5#3=u7RWEg#s6z(Anl zz*xNFnpR}!M&s#gsIS){vY0JdH z{Nv;1X^G7mjTyMrNaGghsG8JojH4>75qqMyV`7^AU-jO4HV=p*m~n9VlJqhj9lz6W!|ow!&_4_NOZfFj1D}`MszQf# z@By_S%)t7ooGvIHHz3#U=S&*~jrb=!tkX*JX$RnF*EUQSy=P(RGxwhSQIsx=`hE(J zh()a?ArqZftyHB@?>rt$Ct!lX6Kx|Vb;$J0YmpVUfxV7y5{Mkzq?efKhu6Pk$+@!= zw{8csbeXQ6Jd+jVH&5v=tuy#c1y9j}$a`7`)Za|k>fo!pk#4|j9Vodx6ej~8Sf`SB zF-{K%%q||Co|O}k2FH)b8_69&T=Y-DZX3Gz-o*5%>gs3JCGjbIQ8;|o`IV(VdB-%@!)bXr%m z4%uok-*ab$kvyWkD_ zLe1}*i@~s-e&9zOy$dNy{2-aIfWrI)NVhV} zUth1hU(fD^?e4CzeywdBvXCI`u7Gx{OMm190XG6gkcwa;kP3&kt1S#aIUYxKsM6Ik z-uAqF_V;21_;zClbX8210o_yl#T+2b6HO4wm4jpPmwSHc z-K;FHX3k>Atld8a@!0)HUzZaw^LYdvu_ikZ;e3g%=y-hN2B&%*w>DXg`nj^4NxMA= zC@BO#;CX6JPWz|)BWebIbgDX@TWG!uTf4gw1hj{1e8la8OgBUp?*ga*(~7w7aYoQ+mb7G$rU zX5V4c!O%~tksY-O4C(pc%`ji#G(WAlO4@ZVtSqzAye9?YlNQ|e5ZS$!M(h{I2bc7E zi-)a7xYxa9zYDE(a6Q%~c*pg4^G|x<&FfesOyAht%*iePyTe(Y?-RFx5A<99<1Q%(wjGbkS4UUyIf~uu|4R} z&neV8*W6Qi4;9K;e~_j8E7LQ948*tF(S~v`;6szvHo%gOlp5^Ln8gh<^XmAZ{QM#q?{DO9-Y#XOCh!q&vN#3;FB+yZsCc7N4G zN7t*N7+@3$Df5LlkFF>M0@5(gGr#LYs?oE1;g+1QcK9w<^)B3rGuL5se!0FJIvpq? zSgOYbFEL@VguC$f2T^T)F$h(Vh{^dz8_h!U=PpxrnS4{d03SmOjE4p?#Ip_QB?-tO zd!AtHT!~L?>9CE8uZ$vCZ@Oaw&ofU7@3Nf5JMBTodWH3Uq0&up>qgQGTF3LdsBrbbioCrC7_ELVTi$peSy!fg{KJZ zrv&Rq(f`9nfsOm$Hae#NjQfvGN%Q|6_s_NrbH61?ca}><9h$H%j{NMQ49m*2xq0Et zs@LC48+wL26DA4A^0==-YJ`B&KDhukHS@zF*=U9)7(s=7={8MP9)124aGj{6Y5HsU zCER2;a`Z#ByLEMZfgBr`V3ui$^ldfov^(!~?k&#TCV>?%L|)|n@mHzzAM~hnbVw1m zncpTJ$)s#Pzkjj5|7iw0xNJiwLI+cvTvGgLmWd@th!JS>*W#mjija(;n#VNB<`fqm zqL{pv_QoFGNJa`aN@>iMZ!s=|B3VvoIa7er=H{^6FHTl_)LO%aic22i=XYAa1a6+~ z`+9&P9aB9X{NqiIODwYGWOB&l+N-{IZ5vfE=BTHP_46v#p|H_2P}$0sw?8@I42DC; zn%Qrny?`E0t+H;=G&Dr!Hu2g@M!#{pD%7fdf^RjJt)J4sPk}Dfic~*YO?@sfjv+Oe zx663Uf7VgNZR{=CIby}Pu6B+?Yk(3wFM-Kt_dhFFFC+kFtww7?fwwHe)AYr6AAic0 z$z0Zz6q>U&B^fCMJw*i?GxlgU8tM-kp!UbXHv5JbS0`cnwA94128mv_9$L=!bi{*P%hotEzW?-#C(UOU@= zE0oLE*47-U8|}~AUt@0BR~JR$EmsncBi^?|a9&9Hb`o>-^mJ8^oP8)~MtU|pcQ<@K zE`PVKG3xObnXY0YM*Ft4V?r)D%$0JkmjCfIo;#CXYOK6D^%itK7|D7*Yy8;5{yWcO zU4S^-sYv!Tc`eWT{=5)^s&9!83tgm2K+x?nDfCc`XJBbx^#x*pkpo}Tm9`_ap?qyl zsR^|5AY?9AT>qIOR2fO5+iz^;V^1Jkg(P+Qcj5BfhV^$nmp@ab3b{o#<#qYnyu9m` zqM~I7C7h?0nucqW2N2xkTP?#Xa>`dcYOPj%Yq#O44b?ClpL({>(5 zKUdP+%;VFwahUrytYwk=l5G;Vp?L* z#tFQ)hQYBap{tZmO^51h)iva?IgILjwC{{nAQJDOy67B~;CyeUjHw;b|6MxaNq*#B z6aYGNaT_SZo}CkdBW>NBygt{^e{UEvy#4;|ec(i+ZNjq#?+T11KWb19@8w~tJKK@d zE+p8dRaI2FjNUR6>+PImNwW|6R%X;2U8q7~SH6Q0pr%2{Vxk0PUU}>LIP0CapneOZ zxaBZ59E7sZNbt*d8Htbs`p{YLX^WvVRRDTx;;<7O7)>qpfALS$@Tv*`F%rw!llDCu3 z#y}0N%nov7qNQcTj4CdD5$iMD3W?yTZ$M5PpO!61?X>1fk_87a6nd}DMV19+|G9G* z)elQ9Ld5XXQz9Xj7CCAzaDmO9J4GAXZ8EGtaT|p-r07ED;J1I~cSwrva7|l43gL?Q zgYt_>bIa$4=y~|kluqXQ)<2kTJme!6cO>>xZpPq`Z!=3x zJyttFznFmicj<(|VU1NrjBVyAp>bt*4{w6x5MY+CyA8qVv^BIz3kX z?xLmcLUo)KPWhJ{PQ-GbF@$2n%=2h=f}+|HUOHOrxN^JNnl)V%l}C z7}eH2_YS1%*E{AW#?Cg6l&1Xy>|BpN7?;Bf(6uK312t^J-{uN*(Rp4l_Q*)pKx`-P zu8o*&5)a-di&@-}4@Hzj%$Tn3bZh!r@>*-=-Wd-8+dd&%yGHa{q zsJuNId=QSvPnqu~2?d4$IOsOr_@U^^n{z+&^mG=S6slFQwq6cpFo17tMzB;GtFOdi zRF@kYy&a~qWd?8ht|&}nU$s%`m&uXQKQEUd4=EgI!jIGA0q^5qEV7}>5WWDb zM2{8|SXKuoByq}->z2RSoF#Ypudf}Tw{?mLQhtXIuRzV~g+!E7p3IU~D`$VvCqf?V z{MwNO`1<4$yhke@uf42Dk`88nXYfb%ec%xrxzHAlr*;*{#0e+#S_EZh_(rr19=^p8gU zV@>}U(m!hTU$%eL>c4FN8+7Y>z99LTjQJJEfe1XI%jT)-vrDnaJbH~538pe{t)EiD z@Rv9yD!u;i-gVL#vi{dApk*X6*@q>@5q-w+70=>8vQT|DOOec``U;- z>4^4UX94Kfa9j96Eq$SPPA0AO4%|h-OnQ+y-{R4Yo!fnMGqC~z$aOY4h2(*;LBG1h zD1M(TjFcEM8Os0==@5oaj2A|@EOJ+qR1?lAXL_i0Fc-`i88dedswD#c1qDn^b(MXr z`-a1Z3f=@8*E}~pQo6eM1TuAH&Npe^1|_|TEdyk2`mG}~MCVpg=;&F@#Mf-2bnbK6 zWxq06!AmfiIUqb`8r33nS5I7br2U2IPRT_TXu~pAvoS5%ym2xaaSxjQ%_)!xbcnJP zlPWGTYh_)cUFAt)`EAh5tu84KP%a}X#eO8==enx6Q?rO05v1nr(%HKkX&y>6oY0?o zGN~`MXcg$;|8wZwU0=*>Zq9dGFT%vMZ#Ad|UXys1OVK=jz(*w6d0B_yrk>C&IAlx z0^BU^Gc@YT*eVPGh2?47viOXM!{Soq1{!WVgT}88ncAK&jr}?$IH}MkHR{bJvzMan zSi78u=F&^{wwFn zbkpo8JYW94gOlX>-mz1br}XbF^25mjU10W)N2Z?AUOR~*+sF*J9}>OE?h@|4qC?Dc zh zYTonwde~y}eCxs}P~4>?6U~ZvWl1Ra*xa`S!rTL0Wul`5WN?Z@JPtqjE1@HH;N$&~ z7pkgwZmTZv^BgE2Rnj_7gRYW(;?kqGT9Rz7Fj8lQ3O_M^+pR)&N#q^0ddcTXV-}v@ zqdwQ($j+34De|Fq!`z1-Xrr!CBwX+(IU%MDd@RN`BkTBH;Fi~V1v^=1@oVX4#(t8d zbmXA)WOpGcdYq=@nP@6(^5o!+7GZ41g^@~jeaRDonhhamvSX)Exwd+mM0?8&7PumQ z@O=8}hXm8u83$0xpnvZQWHv|aw8%5M5@t5;)hsOD-pmt=?eWJ(51Icw&(Bg;l7q~^ zOf(`fBT?DXSs;F|rEtBM3P@YmD#x%NE)khPH4R0#S)rs_nOZ>TO&;_2_tT+fQL9z~ zor=%8R`F+!I1%0l5QHBrw8vLawqPWktUqsk^AZ+79djd;DH}@vOut^7tSn<^8%>(E z>t+q9{G~EE+}mTilW8hWYONUIMZAH;yIDnXzvI4x4<{NNJqX2r!RyOx1c9G>aMBEw ztD9Wc&is5EcR;fJ7@fkL%Pkqldb_ObV!g9bb$7a2FrF!{cwwoPo^)`kqe+YVyitwP zsky97Al<1$*6FS%|E2N8)Kw2_cQ)&e-KAtR_PNSYTJWVEsSXO#1tsym&Kxrod;i@U4}m|lw`_F~kLYwL4TX-=-P%c?b3f&5k8agwBy zfp8@|CMWGWAVbP#K3*G%k?dC*^XGMdwXyk+ar}KZM2Z88(k3luX*)wda(Bbjhua-F zIx|b{pw%mBl~xM-$?{ternMhOQ1>SSXEX}Rq7y=U*)DBPT86arXB(alxH9&4fEEVU^a%m}m=@s6u zc{dg`WUDpq`XPQiwKrc^6dCB~2~1H$3*h`{9pA}!sd3kPs+SFAs78f4O%~OJQqPhZ zKH;fI)42LOJgAjb(_X6v(12JfzHBl=@K4^BT{y_uiKKBivToM>I9Hriul#=$mH#RA zc zcrw~D^lbuN$nuNOOXJuJ`u8b_y_TQ%sO=`8>1Y5HiJ}$E6!Rue_oc}wuHxMvU;UrH zwxFUOY&&|26>i58`<0K-ql2RtfR3L1tN`Fxo{^!aqcN-fb2VAaGvtf2PZo^p91jzr39&6!}FGnucGZ7#om5JSZbdAJ#fR;Q5H#GTDuP0uMt!ove2x@GO^a zlUafw4^Le+zp=<*#gHOMCrwWwVKaDNiSsezhHFGu*~RS(fdns`QcZ5mP9Iugb-y*w z#k^mE+E-@kNK@SS(In|2Hb<3e3Z5uS8m19KjTxdWy*$>r>%}RmS#hWtUjaHo*&08Q zQ+yui0b7=4eojle9BbWn-iu3?{#j_XBqOr^Qu z%*hs5Yj6^yDswe0FoF85RzP8nt3y#`n6#tDCww-qimsBv_w^jUshz}D0PW}=8S1-> zD_BEDbiLS|{J19uoX0N@U@uJfCUU4H$jlp@pZG9Lo@n*ff5?Bru>HMF!&Jsk7R3MH zzz_`EuF3<`+rWUmfc|;od(M8;q_nY&PWAw!4;Sq)KWDg6m>mBvldo#!j2*F|al2TB zN300A>krs7^w%IB{SJb1@L?3ESsiKAL!-1iTG|;=7)ta@tEdYP|JoYeb5d32v-=hceeR2^a@A`=>vV^xIJC{4yhEK|G^7>R)l{aR z*^iN#Y6vZh?0BOjX(k4LAQ1gtwbDLiak8QMc?{+J3l6?HN(ZF~>)e`(-@46n&6!~q zTmQ<-KublHGEAjv{(60-dt1~+|4A};!uIU$QEQ`?8>9M)U-rpc+*6-Y@J$GPB?Y_x z7f@8l5xdw+rAIA6go@0P58gxO`;Dc95elYdCjd)XJa90<{S{DsbJe z_nFza^0SS~^6HINFHXRCVgzaD^s%dZ#(|jLH%;+l&s7YD<(2Oelr3wXA#>Y-y*2io z$5{>C0{&~Q_Hf&#-MtmL5vvr4=N92A>nMhInN1Huj|u3JUrk;nGqRJivrjDbr$mfU zD9&;pXIG{$SDaLsa0O0dzT79g&ByYRbQ<=F!jVqjgrk%N!$;iIo?Pt_SE|w?Qp5=y z93?3V_UV)3M!R+V)~k)Cugu3ZS_UT1-i^hm)(2K!r5)|+a}oamlc{r2mBa5TR+;OQ z#jXUHN{M(_{sfNN18Es}?$wILu&3Z#B>dPu?F2lxiew_Ei6@_|tP9nkeJTC<)TG#G zBFWiLNclNmd0n}GaZTR;Z ziL_M(_o=(&?}Ntox!L3AB*PXj^_tDQmoa4>Ve{+!?J6)LL0xi2C>i4R57D_kcN$ZK za3B^=!44g|jI7n^8=lx~s>-+*Bl^phA7C8d@a=$SRO>x)A31m5#kg&KfG7Ccr*@+K z^KVn=x<6W(3rW&VZMTG`>j!4&JZGR-e6Gs*yt=y#U6O`(f)SR|>d=Xo%id%fziVub zmmMlqC56~a9*&s!i{H!i?ybS0ZQVGUa^PWnxIw6yM-94OyFdz&`^9D)*;iv$6-{v( zQ6-t>BuSqN(>v{TkwYI7Cu+2Da#^>RZ~giKyNqtpraXjU+@aw$dVi02d{ufXzHj(T z(>x^_0b}PbSaPK}=xKa}zizQSMj$mI^c#UPDzN(aSio zfBD`&d8q0AhTtP+gc5s}w+hkPVug}zLoB2adUGV;TfjIoj^^&x-JoTqS(nU*o?&@EvQ~F-cpFMEF4RQ8bepXkzWl8ETl#>-z!2jW^U=ZYfsQ(EJ zo+B9KOtRV>Gdh>7-sb2+X$cdA;Y6wQ#q-6(KKfr*o@n&u9>uY-7ZQ5QCZ1<8nb&z+ zt;41pNA71KV~4l48>S?J@AivjHe>xHp(;!GV@r|fE4xVajXEP8JYTB=i(#*jCL!6l zzHLo^pCh)N*zPZKR2dCv39ZuWqRIuVW#WT)*3QfjZ5)VXV;lvpv%-n@n()M+kmd0q z{oX^l2sr3Opgt9S{_5jiI1Cf|X$xHpFBlwU=Vq=Hg6)r(?l2t0kk$Zx*u~xQIsOsy zZNW-bBWSc@oF5dcr)MVrKmDDNMLY#!8UqHIJ~lJR|0QISHPu^Kv$Bah2=5KEB-B)jf{D{}_DP=i^)nA>)v>K|ZRaxTkZ0|tASGpd zwH*Dcrm1C^#zAPtw#ww_tW_R%eMRY&pn#ZX+NtZ@WIjxrvBjl z3vSUw`#CKoX-Ek@1u>0HvhqP>-B{Y_r+?y$*ceB%gS5|^H1o8vMkO?P5w`o?I>)j| zC_M!M$5Fe_;ETv`%^01CnW-3W7Li7z6ubf+Q50D37RP{zlqfjgF%U0{iE#MVhy#{T zrvIS*kvK|5+EKZ`WAT@9sNOAt{U-o@PyRurh{oJL(q^W%QW4MC$Nm*uCrLDj;`|f> zI!;c-R-JMdy?tEu;oT7nyW|3jYoU!j|Oj3$@B8yaH_=+&iQaKBG|IB!!&LxZ=~gP~NG z0JT||!t|lY zP?~>A=qCxkEW|`FKlfZ7c9%A+|8}%HZ|f&EV()Yryo{F!*0H>3SUf*$o zf9sPmhanb@^530NWO;CbNe^xWG2E5DrGs5V{(PU!-CTY)u*MW`Hi{9J@y<1ucJV`* zp#8%AGl#Dgs(5KXcp>hcZE1=pu1mY_PE`7u7Y@Q_N3pJXD?M*QXjpL%Tfav;m&QGO z##;Rpi}{Y6{pZU)^uNAmg40V3zRnpVqn<F z7}auL-V1=buZAiffR|g0tleC87w_RMeCRRtga6zm1V1GeEj@Q{&~^~5Vc=ZT#j{mQ{xS)Y@8Dx81dG+hSp%2@+kbc4lPD5GDGIUZ$){Ks~PZS)&;; zrV8wMcw9rjy1stj&6FUOD})GEzw$zJef`dlq%cP|JnDaV5@kebMC$dsZakGWT9Qgh z29TPeS!Y~4w;L^ClJ%%?Pn<(TZGfswPd7777;v~LyAf~*Y_OPGuC-s^8H`@6(!oLw zL*sv}bzCbJnAO$}&K%N=25(bVBLlJYwEZYp5C8Y$F)1$hsQDwLN*gBX1sI6!r%h z+Usvjw7DFxf=ROW^8@Ys{ld?WF~(Kzqi>t*-*61Gzzcn?#%Z4$JbOpx|9o6(k>j;6 zzo@UGlzj7q$5<+tlbDmLU+)z?yiY3RPaLYw<$Sx=_CgZynrKtg=DkeoAfN8;$wzGR zpD)6pNMRVe(Ma`e?rOZvdASg}`kgd4JDXSbbc5GUlC12EN*}eI5y13~#B{ZDn8>~7eNBw>` zM8w*2yQAa4TxMrE8+ev=W)crH+6j%~$Pg(Xi06Baq>A(0Pr*agZ2cv?(0)p00c2yQ z51f!QV8b_O^@ZAQgyq0@)kEV=^SfWZjv(_nOHYc^kYV_BnB(^>d6?T`{B&(emwYho zwgq%}KMi`h;Qj;tmxIjdJn^H$tecQoW}25jr1L7$<&5=jLBqQ&3?l^Gl%UW7^8lZX zrQ<@qGsv&tE)qUn6Yxw~=|tE_M#MF7?;43r2@^FW?21ze+}j6tfg# zWEhG2DmG(TR9&r4ZzY|vJ$`BSNQ^qL?PzXcF}xFHw^~7yyincPN&IneH~z30@R6h- zEDcYAgPr{8cYMHY;lszx!U;}paj8%JTm!_~Q$$CD^9>HyJc}U0-r=EqI$OT+i+Ub8 zD{liGRkPVmi4u7pgxdTMO{RsvYlO&+Ma9KkZ@$@!=f1KaR1&@{9es&vu3(P_+&IYi(m>kQhJvOYB_(Bg z;v%t{1%V^S7Po#5ZPWg#-48XgQt+N9x2`M=fM6wy1}n;#V$>unF&^Mcar|s*WO}Mg zG@5|1l^3MyZ=!Eq;s2wtI4CHH(K~u*s}x3ESk$C-Wkplp2x5X8+U_cdE9^#;1!zIT z9L${V=PVd;j*AwPxjNqv5O!H?V2mb9yKsXt@_8q|jaXu{F;%^r*M4WN#R+oHYtlo! zJ#mX9c}|2|6Hj-M;Y&qMetPqY@J@6@ zAx)mbi)4)=rLkeNb36CS3x7s=$C+ixeTMQrm4&j7VPwBXM_&C`f(!$~2~5>0CWN9K zW#dI+?jG!MXVrO`G)-H&nYB zOG(Q4?1Q!8K5Y>Zrtr{f)OAtniz5YEUsBC)Sj9y~X^YfHC2P~i#u=zw>c0+&>^Lse zv{3V$wrX~r6fm2aDW733+#=QvDANzc{aCCIVx&%2D59RykDV43i?QgQE zEL~ivEz<}zo2UbuATu**Yy9OrXKI|5_*KDzu4K2;K2%oDR=J(V73H*fLhpWj0Whhp z3*lP_uNF(Xx23?FaWd+OnbE!Pr{UWtx7n@MI2aw4j`bmE*JPjZ;i{oVUoGzNvf%(4 zaGEg)2@*CB{o`vEQ7xham@kgFYlj+Xgq6cwuqEQFo8e^AfHhNPCvA*7_`Bh{Y?&7f zMx$jP-FZoBg)iM2J|Sa%?aCD}n8$YLi8l=PjF_x-nEi3#IK>KmYZ@x=o3B4?F^uoA@bkqEO_na9(`BbT$C@iDWj zO4mg0O!-|gdn7Y_Ze_KhQj6^_w6!Bm(TV+D6c%rU|OaZp@@OA!8v@R$to`?p{ z_V(#491UgW*$T2Ib~*T}%ROdHkNCRh5+rpS#~q~B&&86;>xbg_`- z6{if!)_(D`!)~qA7!t|mF!GjvFTkc7=kesq)oWWH+>4ns$;foTljqa_fpr#N1VL$? z%*gVix)5Jv*qg-X?$Y!HZn{?$o&Ai=&JBjD5Hfo8t^NCGrlZ?S!LsCkJH7pHrQCmJ z`dwd-HP)fdb3=lVr?~Hv5{-w9jm~vv6=5%Pa`_^E;tDz!(H7F4DvXp!RNWLFSgYhv zU!s@x7KYaPVg>jz&BrIxmE4U37-cAM?fU(yf3ExZ zCBexGs?%M3d%J{u6sfxbyI%EBPUUF0#A$fB0xciuPq%Cd^KYh*aUV>g(P2f-nt}zy(_&O+N)o}bm6=Gr)TnJJFgHg-} z&%`Lnz$g&9V53D(h)RDFuHP%7B2O(SiPWY7aQjH6h1>ZQ# zoUujoUh&*_TE0+HUjE>+mEhD((GXo*WL#EDvd*{VBHd!L@~{^tzC4jta>mpH@VYc+ z+6!vnjG6Q89Z#fFMnskRl};bMoaXjLA37ejJOlx?{$84V(WkLcFPABna~7i>8`eEo z1v9p)nOQkVfz?ybCdL z5qUj2^Qf8aA*rlI6;e>Ke&EIJ>CrnV=9yHQCQ31;*R?cKEX9aabog_21#69Fj3{(l znU!^PzN(j9ZTqW^0s>jfOKVLTU`HGg6~>&!vVfGG`1v|gsuz1kwh1dOS_h1(>qu6G z8yHyyYkKGwfbz@BjfC*lW@ zV5A#rRRqmyf}C#66~3cPG2E;_W0la(>Wtt6}kA|i}$Taqz%zzqe*SN(!y z^c&I}bPeEx^3J)}m7aKcm6d+&7wi8fdf>7Ozl@0R2^o6<8vvTaVE~mQW;6l*wQrqo zvbu_~NzNOr2Ve!oA(+XT4>zbH?c`662c2&+Mjg*^GSn+=Bt(K1A9_53^IW6^wo?J* zeSm+7)xDi5V!otD+tc=@;%;1@*mO(H)2_%klU177lHQc=V;wT%-u^NoV$}*|dWUOZ z8@K6hAy$|6K80nC`kkMP<4TNrIm7-{6rauelbY_t+zI_~F2i7HwpSX@qwb%O4NLQ4 z)1l@N#!uL=d>W5Ua9@<#m@w3Og zD-O3?X~MbzEFabRCmIp`3&t*;M=lY-%S?mthHwLv+yRp@b87Z-ZJw0jVs3jir*U)D zN8Th=V084fFk@I6ieVrVOUKld!64>9uh+}W3d21&dz5v)g>?^j!ip=)=egpeGBe#V zl}8dRbaXrc*ktW43Rptnb=>wlKqIs7pUU`B!2bt@s1si)+-u>dUr>>rk~Z}KJ|Kxz z2F&U@-xgS2*FWM=6w=yedIVN#n94*XulDIZ_`I~QkmaQ`zZ0O?4%CUDaM9RmiGOf{ zp$A=F>fzD1OV=aFM+jOOa~6@H$Dv0joFJISxq0vy6Z20luBOLaHkxP^DHW7NlG4D^ z{>rsi=-g_Y*@RnB_}iO5~mk zvCJek+ZkFIQi&IbD-F^AM4Sd<38^|d`r%u3CGYK}^%v?$V;gh%9Uax5AL>H&gYJze zqsw1s^*HU9nvTFIn!{XZOn{k^7kApv6rtu3vRbrZnR#rO?bV=EIE4%2Ff-Q#-h z>&*^bKfhU8QqkL;OCoEHl34({o#=XVt{Xxw0h$$Iqt;{d!Phf3K&wC=J^*4sCo=wt!<=AEVqEJ|IxsXSfKL4T1^Jk!`2t8JLaLyPG7Id> zak#&anV5XV1x+Ok5$5)HNE9)~;2}xM_#dTamTqf#CrB~ahxMUVW}_?jM>5yvty1D5iNi@0qJ6%J>bdqZk!|)CZS+kFz>|^nYlp z^3yy0(wfoc)Q7pn9Ouw;e2uub0_u3;P1NMby!bi)Ej^nlTaVr0W&lSIP?FL3SSAgR zM%;&%(AQx=Y1$z@iz$vZ73kI9PjpO*L253zWB|k`H!Q9s=j6=uiB~FbwcOM9cX@p0 zN5{;Fj7p=6!Ocr|YquN3uJ{!`<@a^ImHJJkwI1J6Gs^D$`*>okjae;gVD;Hv>cWPX zzLt?AH;0{(M&kbALa_f5!$Q+q_JAmp@~`-waN_#G!QjO$46`3$a_X3%<+R4OD-MJAQrrE50Nqn_x@+Tbue{@cb`X{7>2amH$7E z{KpCZ^QZFvwk{F28Dt<4fC2s@0!q5S!XOcV6#j!5{!!#Ph5Vz0=S4)+me$l5S4EsL z#4vI)i+s{j`^SF;68=@Y!5mlO@0~}$6zHp1 zQBqV~9m-V!fO$FG6ax9^v)JJ&`w>o;fSnA+C^(YWc(^`N0*xhJ|Mz^=TWIQ*?jG zw{14Bt5F9A1_I4^c?K0r?+dTC|MHT!g8`KL2G}e@`?pd<)Sdltlbuf+vkgO!aUX#0 znxCJ)oXgOFg=bpQK0V#Xq>I~dsR@dUZ*6Sc$tg0dx9f~17R=1dAd$#2^G~BFUAm;8 zoBrAUC8ebh2*glP5L57lK1%(5%uCK z)7z#&(aM%zI^p4GMQ!txr4a%-Pwn^DCU_zrr1D>_nAmaVyc;ZiHdRqk(I@t?Kl*tf z?I5<6W?*0-hKW1pZU~%|*1Mx?Mc=iLv1td|1yUn5;{7r4`5#(ZLRb4Ucp?MWCkK!+ zebLmD5qddyg8C4m;w{@9-#@=Vt&P)jD~GO6md9z>uZnPHzEmO@$!%!Ll=N5b?S+UiHaUx3yM)J7HVnPc6uqM zlp?wPMF60emY0{yMvB}1TK<+P3ls8*>ND%Oz#?K%<+suc>KHFJx#%Y;oZh#;x3^sB z9RP=0KRa5HC5luq|H@b$%+745>4P!YNFQeC@n`5ogV5d!%CFNWF-twgG6f!t8PGt%kN(rsGGK9vDG)$RoL z!_ODFmvd7utI(j8H<@zYvNJd~<*a=6(U!vw6CU~`Q-C8ZTLOv=p00XjN5nh9)XCMK!h97pj1q)GVS40Rr2jSVMj XevPuLoJjzk|9)`aK%+v<_W8d78{4Ct diff --git a/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/StateBuilder.java b/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/StateBuilder.java deleted file mode 100644 index c4dca8ae..00000000 --- a/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/StateBuilder.java +++ /dev/null @@ -1,66 +0,0 @@ -package foo.bar.example.forereactiveui.ui.wallet; - -import androidx.test.InstrumentationRegistry; -import androidx.test.rule.ActivityTestRule; - -import co.early.fore.core.WorkMode; -import foo.bar.example.forereactiveui.App; -import foo.bar.example.forereactiveui.OG; -import foo.bar.example.forereactiveui.feature.wallet.Wallet; - -import static org.mockito.Mockito.when; - -/** - * - */ -public class StateBuilder { - - private Wallet mockWallet; - - StateBuilder(Wallet mockWallet) { - this.mockWallet = mockWallet; - } - - StateBuilder withMobileWalletMaximum(int totalFundsAvailable) { - when(mockWallet.getMobileWalletAmount()).thenReturn(totalFundsAvailable); - when(mockWallet.getSavingsWalletAmount()).thenReturn(0); - when(mockWallet.canDecrease()).thenReturn(true); - when(mockWallet.canIncrease()).thenReturn(false); - return this; - } - - StateBuilder withMobileWalletHalfFull(int savingsWalletAmount, int mobileWalletAmount) { - when(mockWallet.getMobileWalletAmount()).thenReturn(mobileWalletAmount); - when(mockWallet.getSavingsWalletAmount()).thenReturn(savingsWalletAmount); - when(mockWallet.canDecrease()).thenReturn(true); - when(mockWallet.canIncrease()).thenReturn(true); - return this; - } - - StateBuilder withMobileWalletEmpty(int totalFundsAvailable) { - when(mockWallet.getMobileWalletAmount()).thenReturn(0); - when(mockWallet.getSavingsWalletAmount()).thenReturn(totalFundsAvailable); - when(mockWallet.canDecrease()).thenReturn(false); - when(mockWallet.canIncrease()).thenReturn(true); - return this; - } - - - ActivityTestRule createRule(){ - - return new ActivityTestRule(WalletsActivity.class) { - @Override - protected void beforeActivityLaunched() { - - //get hold of the application - App app = (App) InstrumentationRegistry.getTargetContext().getApplicationContext(); - OG.setApplication(app, WorkMode.SYNCHRONOUS); - - //inject our mocks so our UI layer will pick them up - OG.putMock(Wallet.class, mockWallet); - } - - }; - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/WalletsViewTest.java b/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/WalletsViewTest.java deleted file mode 100644 index a3f0b594..00000000 --- a/app-examples/example-jv-01reactiveui/src/androidTest/java/foo/bar/example/forereactiveui/ui/wallet/WalletsViewTest.java +++ /dev/null @@ -1,150 +0,0 @@ -package foo.bar.example.forereactiveui.ui.wallet; - -import android.app.Activity; -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import foo.bar.example.forereactiveui.R; -import foo.bar.example.forereactiveui.feature.wallet.Wallet; - -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; -import static androidx.test.espresso.Espresso.onView; -import static androidx.test.espresso.action.ViewActions.click; -import static androidx.test.espresso.assertion.ViewAssertions.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; -import static androidx.test.espresso.matcher.ViewMatchers.withId; -import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.not; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Here we make sure that the view elements accurately reflect the state of the models - * and that clicking the buttons results in the correct action being performed - */ -@RunWith(AndroidJUnit4.class) -public class WalletsViewTest { - - - private Wallet mockWallet; - - - @Before - public void setup(){ - - //MockitoAnnotations.initMocks(WalletView.this); - System.setProperty("dexmaker.dexcache", InstrumentationRegistry.getTargetContext().getCacheDir().getPath()); - - mockWallet = mock(Wallet.class); - - } - - @Test - public void emptyMobileWallet() throws Exception { - - //arrange - new StateBuilder(mockWallet) - .withMobileWalletEmpty(100) - .createRule() - .launchActivity(null); - - //act - - //assert - onView(withId(R.id.wallet_increase_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_decrease_btn)).check(matches(not(isEnabled()))); - onView(withId(R.id.wallet_mobileamount_txt)).check(matches(withText("0"))); - onView(withId(R.id.wallet_savingsamount_txt)).check(matches(withText("100"))); - } - - @Test - public void fullMobileWallet() throws Exception { - - //arrange - new StateBuilder(mockWallet) - .withMobileWalletMaximum(100) - .createRule() - .launchActivity(null); - - //act - - //assert - onView(withId(R.id.wallet_increase_btn)).check(matches(not(isEnabled()))); - onView(withId(R.id.wallet_decrease_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_mobileamount_txt)).check(matches(withText("100"))); - onView(withId(R.id.wallet_savingsamount_txt)).check(matches(withText("0"))); - } - - @Test - public void halfFullMobileWallet() throws Exception { - - //arrange - new StateBuilder(mockWallet) - .withMobileWalletHalfFull(32, 8) - .createRule() - .launchActivity(null); - - //act - - //assert - onView(withId(R.id.wallet_increase_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_decrease_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_mobileamount_txt)).check(matches(withText("8"))); - onView(withId(R.id.wallet_savingsamount_txt)).check(matches(withText("32"))); - } - - @Test - public void stateMaintainedAfterRotation() throws Exception { - - //arrange - Activity activity = new StateBuilder(mockWallet) - .withMobileWalletHalfFull(200, 10) - .createRule() - .launchActivity(null); - activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); - onView(withId(R.id.wallet_mobileamount_txt)).check(matches(withText("10"))); - - //act - activity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); - - //assert - onView(withId(R.id.wallet_increase_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_decrease_btn)).check(matches(isEnabled())); - onView(withId(R.id.wallet_mobileamount_txt)).check(matches(withText("10"))); - onView(withId(R.id.wallet_savingsamount_txt)).check(matches(withText("200"))); - } - - @Test - public void clickIncreaseCallsModel() throws Exception { - //arrange - new StateBuilder(mockWallet) - .withMobileWalletHalfFull(32, 8) - .createRule() - .launchActivity(null); - //act - onView(withId(R.id.wallet_increase_btn)).perform(click()); - - //assert - verify(mockWallet).increaseMobileWallet(); - } - - @Test - public void clickDecreaseCallsModel() throws Exception { - //arrange - new StateBuilder(mockWallet) - .withMobileWalletHalfFull(32, 8) - .createRule() - .launchActivity(null); - //act - onView(withId(R.id.wallet_decrease_btn)).perform(click()); - - //assert - verify(mockWallet).decreaseMobileWallet(); - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/main/AndroidManifest.xml b/app-examples/example-jv-01reactiveui/src/main/AndroidManifest.xml deleted file mode 100644 index 2ff67c60..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/AndroidManifest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - diff --git a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/App.java b/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/App.java deleted file mode 100644 index 7a450ec5..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/App.java +++ /dev/null @@ -1,26 +0,0 @@ -package foo.bar.example.forereactiveui; - -import android.app.Application; - -/** - * Try not to fill this class with lots of code, if possible move it to a model somewhere - */ -public class App extends Application { - - private static App inst; - - @Override - public void onCreate() { - super.onCreate(); - - inst = this; - - OG.setApplication(inst); - OG.init(); - } - - public static App getInst() { - return inst; - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/OG.java b/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/OG.java deleted file mode 100644 index 9ce14ea4..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/OG.java +++ /dev/null @@ -1,72 +0,0 @@ -package foo.bar.example.forereactiveui; - -import android.app.Application; - -import java.util.HashMap; -import java.util.Map; - -import co.early.fore.core.WorkMode; -import co.early.fore.core.logging.AndroidLogger; -import foo.bar.example.forereactiveui.feature.wallet.Wallet; - -import static co.early.fore.core.Affirm.notNull; - -/** - * - * OG - Object Graph, pure DI implementation - * - * Copyright © 2019 early.co. All rights reserved. - */ -public class OG { - - private static boolean initialized = false; - private static final Map, Object> dependencies = new HashMap<>(); - - - public static void setApplication(Application application) { - setApplication(application, WorkMode.ASYNCHRONOUS); - } - - public static void setApplication(Application application, final WorkMode workMode) { - - notNull(application); - notNull(workMode); - - - // create dependency graph - AndroidLogger logger = new AndroidLogger("fore_"); - Wallet wallet = new Wallet(logger); - - - // add models to the dependencies map if you will need them later - dependencies.put(Wallet.class, wallet); - - } - - public static void init() { - if (!initialized) { - initialized = true; - - // run any necessary initialization code once object graph has been created here - - } - } - - public static T get(Class model) { - - notNull(model); - T t = model.cast(dependencies.get(model)); - notNull(t); - - return t; - } - - public static void putMock(Class clazz, T object) { - - notNull(clazz); - notNull(object); - - dependencies.put(clazz, object); - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/feature/wallet/Wallet.java b/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/feature/wallet/Wallet.java deleted file mode 100644 index 59c5d8fd..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/feature/wallet/Wallet.java +++ /dev/null @@ -1,59 +0,0 @@ -package foo.bar.example.forereactiveui.feature.wallet; - - -import co.early.fore.core.Affirm; -import co.early.fore.core.WorkMode; -import co.early.fore.core.logging.Logger; -import co.early.fore.core.observer.ObservableImp; - -/** - * - */ -public class Wallet extends ObservableImp { - - private static final String TAG = Wallet.class.getSimpleName(); - - private final Logger logger; - public final int totalDollarsAvailable = 10; - private int mobileWalletDollars = 0; - - - public Wallet(Logger logger) { - super(WorkMode.SYNCHRONOUS, logger); - this.logger = Affirm.notNull(logger); - } - - - public void increaseMobileWallet() { - if (canIncrease()) { - mobileWalletDollars++; - logger.i(TAG, "Increasing mobile wallet to:" + mobileWalletDollars); - notifyObservers(); - } - } - - public void decreaseMobileWallet(){ - if (canDecrease()) { - mobileWalletDollars--; - logger.i(TAG, "Decreasing mobile wallet to:" + mobileWalletDollars); - notifyObservers(); - } - } - - public int getMobileWalletAmount(){ - return mobileWalletDollars; - } - - public int getSavingsWalletAmount(){ - return totalDollarsAvailable - mobileWalletDollars; - } - - public boolean canIncrease(){ - return mobileWalletDollars0; - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/ui/wallet/WalletsActivity.java b/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/ui/wallet/WalletsActivity.java deleted file mode 100644 index 94dc7e68..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/java/foo/bar/example/forereactiveui/ui/wallet/WalletsActivity.java +++ /dev/null @@ -1,85 +0,0 @@ -package foo.bar.example.forereactiveui.ui.wallet; - -import android.os.Bundle; -import android.widget.Button; -import android.widget.TextView; - -import androidx.fragment.app.FragmentActivity; -import butterknife.BindView; -import butterknife.ButterKnife; -import co.early.fore.core.observer.Observer; -import foo.bar.example.forereactiveui.OG; -import foo.bar.example.forereactiveui.R; -import foo.bar.example.forereactiveui.feature.wallet.Wallet; - - -public class WalletsActivity extends FragmentActivity { - - //models that we need to sync with - private Wallet wallet = OG.get(Wallet.class); - - - //UI elements that we care about - @BindView(R.id.wallet_increase_btn) - public Button increaseMobileWalletBtn; - - @BindView(R.id.wallet_decrease_btn) - public Button decreaseMobileWalletBtn; - - @BindView(R.id.wallet_mobileamount_txt) - public TextView mobileWalletAmount; - - @BindView(R.id.wallet_savingsamount_txt) - public TextView savingsWalletAmount; - - - //single observer reference - Observer observer = this::syncView; - - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_wallet); - - ButterKnife.bind(this); - - setupButtonClickListeners(); - } - - private void setupButtonClickListeners() { - increaseMobileWalletBtn.setOnClickListener(v -> { - wallet.increaseMobileWallet();//notice how the data binding takes care of updating the view for you - }); - decreaseMobileWalletBtn.setOnClickListener(v -> { - wallet.decreaseMobileWallet();//notice how the data binding takes care of updating the view for you - }); - } - - - //reactive UI stuff below - - public void syncView(){ - increaseMobileWalletBtn.setEnabled(wallet.canIncrease()); - decreaseMobileWalletBtn.setEnabled(wallet.canDecrease()); - mobileWalletAmount.setText("" + wallet.getMobileWalletAmount()); - savingsWalletAmount.setText("" + wallet.getSavingsWalletAmount()); - } - - @Override - protected void onStart() { - super.onStart(); - wallet.addObserver(observer); - syncView(); // <- don't forget this - } - - - @Override - protected void onStop() { - super.onStop(); - wallet.removeObserver(observer); - } - -} diff --git a/app-examples/example-jv-01reactiveui/src/main/res/drawable-xxhdpi/moneybag.png b/app-examples/example-jv-01reactiveui/src/main/res/drawable-xxhdpi/moneybag.png deleted file mode 100644 index e0ce7a83a0d4c2c453fc1ba0f8938db2af58d2fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16471 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 YVYFqwURfG=cnCvXSx2c}(Kh=30H;ldC;$Ke diff --git a/app-examples/example-jv-01reactiveui/src/main/res/layout/activity_wallet.xml b/app-examples/example-jv-01reactiveui/src/main/res/layout/activity_wallet.xml deleted file mode 100644 index d86c8bf0..00000000 --- a/app-examples/example-jv-01reactiveui/src/main/res/layout/activity_wallet.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - -