From 88f43a78515cda66bd9ea123416e055ee1b0fe8a Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 10 Apr 2026 15:55:42 +0200 Subject: [PATCH 01/25] chore: sync with repositories base --- .../actions/setup-android-gradle/action.yml | 49 + .../convert_instrumentation_to_junit.py | 63 + .../android/convert_instrumentation_tree.sh | 39 + .../android/enable_kvm_if_available.sh | 11 + .../install_system_image_with_retry.sh | 60 + .../run_all_instrumentation_variants.sh | 126 + .../android/run_emulator_instrumentation.sh | 67 + .../android/validate_debug_apk_tasks.sh | 8 + .github/scripts/codeql/build_for_codeql.sh | 12 + .github/scripts/pr/build_pr_summary.py | 162 + .../scripts/pr/list_downloaded_artifacts.sh | 4 + .github/scripts/preflight/classify_changes.sh | 58 + .github/scripts/preflight/write_summary.sh | 24 + .github/scripts/quality/run_coverage.sh | 11 + .../quality/run_debug_build_and_unit_tests.sh | 14 + ...run_debug_build_and_unit_tests_windows.ps1 | 18 + .github/scripts/quality/run_foundation.sh | 11 + .../scripts/quality/write_coverage_summary.sh | 9 + .../quality/write_foundation_summary.sh | 10 + .github/scripts/release/assemble_release.sh | 9 + .github/scripts/release/lint_release.sh | 9 + .github/scripts/security/run_gitleaks.sh | 11 + .../setup/install_android_sdk_packages.sh | 28 + .../install_android_sdk_packages_windows.ps1 | 48 + .github/workflows/android-tests.yml | 109 + .github/workflows/ci.yml | 346 +- .github/workflows/codeql.yml | 42 + .github/workflows/pr-report.yml | 98 + .github/workflows/preflight.yml | 65 + .github/workflows/quality.yml | 263 ++ .github/workflows/release.yml | 73 + .github/workflows/security.yml | 41 + .github/workflows/supply-chain.yml | 18 + .gitignore | 1 + README.md | 20 +- ai/build.gradle.kts | 12 +- ai/gradle.lockfile | 279 +- app/build.gradle.kts | 29 +- app/gradle.lockfile | 462 ++- app/src/main/AndroidManifest.xml | 6 +- .../main/java/com/itlab/notes/MainActivity.kt | 34 +- .../main/java/com/itlab/notes/ui/NotesApp.kt | 48 + .../com/itlab/notes/ui/NotesUiContract.kt | 53 + .../java/com/itlab/notes/ui/NotesViewModel.kt | 162 + .../com/itlab/notes/ui/editor/EditorScreen.kt | 189 +- .../itlab/notes/ui/editor/EditorViewModel.kt | 32 +- .../itlab/notes/ui/notes/DirectoriesScreen.kt | 148 + .../itlab/notes/ui/notes/DirectoryItemUi.kt | 6 + .../com/itlab/notes/ui/notes/NoteItemUi.kt | 7 + .../com/itlab/notes/ui/notes/NotesScreen.kt | 202 +- .../java/com/itlab/notes/ui/theme/Theme.kt | 24 +- .../java/com/itlab/notes/ui/theme/Type.kt | 17 - app/src/main/res/values/colors.xml | 3 + build.gradle.kts | 7 +- data/build.gradle.kts | 35 +- data/gradle.lockfile | 382 +- .../java/com/itlab/data/FolderDaoTest.kt | 72 + .../com/itlab/data/NoteAndMediaCascadeTest.kt | 70 + .../main/java/com/itlab/data/dao/FolderDao.kt | 37 + .../main/java/com/itlab/data/dao/MediaDao.kt | 33 + .../main/java/com/itlab/data/dao/NoteDao.kt | 43 + .../java/com/itlab/data/db/AppDatabase.kt | 25 + .../com/itlab/data/db/DateTimeConverters.kt | 15 + .../com/itlab/data/db/MetadataConverter.kt | 21 + .../com/itlab/data/entity/FolderEntity.kt | 16 + .../java/com/itlab/data/entity/MediaEntity.kt | 30 + .../java/com/itlab/data/entity/NoteEntity.kt | 21 + .../com/itlab/data/mapper/NoteFolderMapper.kt | 32 + .../java/com/itlab/data/mapper/NoteMapper.kt | 95 + .../repository/NoteFolderRepositoryImpl.kt | 45 + .../data/repository/NotesRepositoryImpl.kt | 48 +- .../java/com/itlab/data/ExampleUnitTest.kt | 21 - .../java/com/itlab/data/dao/MediaDaoTest.kt | 147 + .../java/com/itlab/data/dao/NoteDaoTest.kt | 147 + .../java/com/itlab/data/db/AppDatabaseTest.kt | 39 + .../itlab/data/db/DateTimeConvertersTest.kt | 28 + .../itlab/data/db/MetadataConverterTest.kt | 25 + .../com/itlab/data/entity/FolderEntityTest.kt | 3 + .../com/itlab/data/entity/MediaEntityTest.kt | 63 + .../com/itlab/data/entity/NoteEntityTest.kt | 113 + .../itlab/data/mapper/NoteFolderMapperTest.kt | 67 + .../com/itlab/data/mapper/NoteMapperTest.kt | 164 + .../NoteFolderRepositoryImplTest.kt | 154 + .../repository/NotesRepositoryImplTest.kt | 245 ++ docs/README.md | 17 + docs/developer/README.md | 226 ++ docs/developer/ci-local.md | 414 ++ docs/developer/project.md | 40 + domain/build.gradle.kts | 15 +- domain/gradle.lockfile | 280 +- .../java/com/itlab/domain/ai/NoteAiService.kt | 9 + .../domain/aiusecase/ApplySummaryUseCase.kt | 26 + .../domain/aiusecase/ApplyTagsUseCase.kt | 26 + .../domain/aiusecase/SuggestSummaryUseCase.kt | 25 + .../domain/aiusecase/SuggestTagsUseCase.kt | 34 + .../com/itlab/domain/cloud/CloudDataSource.kt | 34 + .../com/itlab/domain/cloud/SyncManager.kt | 25 + .../main/java/com/itlab/domain/model/Note.kt | 70 +- .../java/com/itlab/domain/model/NoteFolder.kt | 13 + .../domain/repository/NoteFolderRepository.kt | 21 + .../domain/repository/NotesRepository.kt | 17 +- .../domain/usecase/CreateFolderUseCase.kt | 15 + .../itlab/domain/usecase/CreateNoteUseCase.kt | 14 + .../domain/usecase/DeleteFolderUseCase.kt | 11 + .../itlab/domain/usecase/DeleteNoteUseCase.kt | 11 + .../itlab/domain/usecase/GetFolderUseCase.kt | 10 + .../itlab/domain/usecase/GetNoteUseCase.kt | 10 + .../domain/usecase/MoveNoteToFolderUseCase.kt | 17 + .../domain/usecase/ObserveFoldersUseCase.kt | 11 + .../usecase/ObserveNotesByFolderUseCase.kt | 15 + .../domain/usecase/ObserveNotesUseCase.kt | 11 + .../domain/usecase/UpdateFolderUseCase.kt | 14 + .../itlab/domain/usecase/UpdateNoteUseCase.kt | 14 + .../java/com/itlab/domain/AIUseCasesTest.kt | 246 ++ .../java/com/itlab/domain/ExampleUnitTest.kt | 26 - .../com/itlab/domain/FolderUseCasesTest.kt | 122 + .../java/com/itlab/domain/NoteFolderTest.kt | 24 + .../test/java/com/itlab/domain/NoteTest.kt | 51 + .../java/com/itlab/domain/NoteUseCasesTest.kt | 131 + gradle.properties | 6 +- gradle/gradle-daemon-jvm.properties | 12 + gradle/libs.versions.toml | 42 +- gradle/verification-metadata.xml | 3385 ++++++++++++++++- gradle/wrapper/gradle-wrapper.jar | Bin 45457 -> 48966 bytes gradle/wrapper/gradle-wrapper.properties | 6 +- gradlew | 5 +- gradlew.bat | 187 +- settings.gradle.kts | 3 + 128 files changed, 10599 insertions(+), 985 deletions(-) create mode 100644 .github/actions/setup-android-gradle/action.yml create mode 100644 .github/scripts/android/convert_instrumentation_to_junit.py create mode 100644 .github/scripts/android/convert_instrumentation_tree.sh create mode 100644 .github/scripts/android/enable_kvm_if_available.sh create mode 100644 .github/scripts/android/install_system_image_with_retry.sh create mode 100644 .github/scripts/android/run_all_instrumentation_variants.sh create mode 100644 .github/scripts/android/run_emulator_instrumentation.sh create mode 100644 .github/scripts/android/validate_debug_apk_tasks.sh create mode 100644 .github/scripts/codeql/build_for_codeql.sh create mode 100644 .github/scripts/pr/build_pr_summary.py create mode 100644 .github/scripts/pr/list_downloaded_artifacts.sh create mode 100644 .github/scripts/preflight/classify_changes.sh create mode 100644 .github/scripts/preflight/write_summary.sh create mode 100644 .github/scripts/quality/run_coverage.sh create mode 100644 .github/scripts/quality/run_debug_build_and_unit_tests.sh create mode 100644 .github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1 create mode 100644 .github/scripts/quality/run_foundation.sh create mode 100644 .github/scripts/quality/write_coverage_summary.sh create mode 100644 .github/scripts/quality/write_foundation_summary.sh create mode 100644 .github/scripts/release/assemble_release.sh create mode 100644 .github/scripts/release/lint_release.sh create mode 100644 .github/scripts/security/run_gitleaks.sh create mode 100644 .github/scripts/setup/install_android_sdk_packages.sh create mode 100644 .github/scripts/setup/install_android_sdk_packages_windows.ps1 create mode 100644 .github/workflows/android-tests.yml create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/pr-report.yml create mode 100644 .github/workflows/preflight.yml create mode 100644 .github/workflows/quality.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/security.yml create mode 100644 .github/workflows/supply-chain.yml create mode 100644 app/src/main/java/com/itlab/notes/ui/NotesApp.kt create mode 100644 app/src/main/java/com/itlab/notes/ui/NotesUiContract.kt create mode 100644 app/src/main/java/com/itlab/notes/ui/NotesViewModel.kt create mode 100644 app/src/main/java/com/itlab/notes/ui/notes/DirectoriesScreen.kt create mode 100644 app/src/main/java/com/itlab/notes/ui/notes/DirectoryItemUi.kt create mode 100644 app/src/main/java/com/itlab/notes/ui/notes/NoteItemUi.kt create mode 100644 app/src/main/res/values/colors.xml create mode 100644 data/src/androidTest/java/com/itlab/data/FolderDaoTest.kt create mode 100644 data/src/androidTest/java/com/itlab/data/NoteAndMediaCascadeTest.kt create mode 100644 data/src/main/java/com/itlab/data/dao/FolderDao.kt create mode 100644 data/src/main/java/com/itlab/data/dao/MediaDao.kt create mode 100644 data/src/main/java/com/itlab/data/dao/NoteDao.kt create mode 100644 data/src/main/java/com/itlab/data/db/AppDatabase.kt create mode 100644 data/src/main/java/com/itlab/data/db/DateTimeConverters.kt create mode 100644 data/src/main/java/com/itlab/data/db/MetadataConverter.kt create mode 100644 data/src/main/java/com/itlab/data/entity/FolderEntity.kt create mode 100644 data/src/main/java/com/itlab/data/entity/MediaEntity.kt create mode 100644 data/src/main/java/com/itlab/data/entity/NoteEntity.kt create mode 100644 data/src/main/java/com/itlab/data/mapper/NoteFolderMapper.kt create mode 100644 data/src/main/java/com/itlab/data/mapper/NoteMapper.kt create mode 100644 data/src/main/java/com/itlab/data/repository/NoteFolderRepositoryImpl.kt delete mode 100644 data/src/test/java/com/itlab/data/ExampleUnitTest.kt create mode 100644 data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt create mode 100644 data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt create mode 100644 data/src/test/java/com/itlab/data/db/AppDatabaseTest.kt create mode 100644 data/src/test/java/com/itlab/data/db/DateTimeConvertersTest.kt create mode 100644 data/src/test/java/com/itlab/data/db/MetadataConverterTest.kt create mode 100644 data/src/test/java/com/itlab/data/entity/FolderEntityTest.kt create mode 100644 data/src/test/java/com/itlab/data/entity/MediaEntityTest.kt create mode 100644 data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt create mode 100644 data/src/test/java/com/itlab/data/mapper/NoteFolderMapperTest.kt create mode 100644 data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt create mode 100644 data/src/test/java/com/itlab/data/repository/NoteFolderRepositoryImplTest.kt create mode 100644 data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt create mode 100644 docs/README.md create mode 100644 docs/developer/README.md create mode 100644 docs/developer/ci-local.md create mode 100644 docs/developer/project.md create mode 100644 domain/src/main/java/com/itlab/domain/ai/NoteAiService.kt create mode 100644 domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt create mode 100644 domain/src/main/java/com/itlab/domain/cloud/SyncManager.kt create mode 100644 domain/src/main/java/com/itlab/domain/model/NoteFolder.kt create mode 100644 domain/src/main/java/com/itlab/domain/repository/NoteFolderRepository.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt create mode 100644 domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt create mode 100644 domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt delete mode 100644 domain/src/test/java/com/itlab/domain/ExampleUnitTest.kt create mode 100644 domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt create mode 100644 domain/src/test/java/com/itlab/domain/NoteFolderTest.kt create mode 100644 domain/src/test/java/com/itlab/domain/NoteTest.kt create mode 100644 domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt create mode 100644 gradle/gradle-daemon-jvm.properties diff --git a/.github/actions/setup-android-gradle/action.yml b/.github/actions/setup-android-gradle/action.yml new file mode 100644 index 0000000..be46906 --- /dev/null +++ b/.github/actions/setup-android-gradle/action.yml @@ -0,0 +1,49 @@ +name: Setup Android Gradle +description: Sets up Java, Android SDK, Gradle, and required SDK packages + +inputs: + java-version: + description: Java version to install + required: false + default: "17" + android-api-level: + description: Android API level platform to install + required: true + android-build-tools: + description: Android build tools version to install + required: true + install-system-image: + description: Whether to install an emulator system image + required: false + default: "false" + android-system-image: + description: Full sdkmanager system image coordinate + required: false + default: "" + +runs: + using: composite + steps: + - name: Set up Java + uses: actions/setup-java@v5.2.0 + with: + distribution: temurin + java-version: ${{ inputs.java-version }} + cache: gradle + + - name: Set up Android SDK + uses: android-actions/setup-android@v3.2.2 + with: + packages: platform-tools + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v5.0.2 + + - name: Install Android SDK packages + shell: bash + env: + ANDROID_API_LEVEL: ${{ inputs.android-api-level }} + ANDROID_BUILD_TOOLS: ${{ inputs.android-build-tools }} + INSTALL_SYSTEM_IMAGE: ${{ inputs.install-system-image }} + ANDROID_SYSTEM_IMAGE: ${{ inputs.android-system-image }} + run: bash "$GITHUB_ACTION_PATH/../../scripts/setup/install_android_sdk_packages.sh" diff --git a/.github/scripts/android/convert_instrumentation_to_junit.py b/.github/scripts/android/convert_instrumentation_to_junit.py new file mode 100644 index 0000000..7b16ee1 --- /dev/null +++ b/.github/scripts/android/convert_instrumentation_to_junit.py @@ -0,0 +1,63 @@ +import pathlib +import re +import sys +import xml.etree.ElementTree as ET + + +def arg(index: int, default: str) -> str: + try: + return sys.argv[index] + except IndexError: + return default + + +raw_path = pathlib.Path(arg(1, "instrumentation-raw.txt")) +output_xml = pathlib.Path(arg(2, "instrumentation-results.xml")) +output_txt = pathlib.Path(arg(3, "instrumentation.txt")) +suite_name = arg(4, "androidTest") + +if not raw_path.exists(): + raise SystemExit(f"{raw_path} was not generated") + +raw = raw_path.read_text() +suite = ET.Element("testsuite", name=suite_name, tests="0", failures="0", errors="0", skipped="0") +tests = failures = 0 +current_class = "unknown" +current_test = "unknown" +current_stack = "" + +for line in raw.splitlines(): + line = line.strip() + m_class = re.match(r"INSTRUMENTATION_STATUS: class=(.+)", line) + m_test = re.match(r"INSTRUMENTATION_STATUS: test=(.+)", line) + m_stack = re.match(r"INSTRUMENTATION_STATUS: stack=(.+)", line) + m_code = re.match(r"INSTRUMENTATION_STATUS_CODE: (-?\d+)", line) + + if m_class: + current_class = m_class.group(1) + elif m_test: + current_test = m_test.group(1) + elif m_stack: + current_stack = m_stack.group(1) + elif m_code: + code = int(m_code.group(1)) + if code in (0, -2): + tests += 1 + testcase = ET.SubElement( + suite, + "testcase", + classname=current_class, + name=current_test, + ) + if code == -2: + failures += 1 + failure = ET.SubElement(testcase, "failure", message="Instrumentation failure") + failure.text = current_stack or "Unknown instrumentation failure" + current_stack = "" + +suite.set("tests", str(tests)) +suite.set("failures", str(failures)) +tree = ET.ElementTree(suite) +ET.indent(tree, space=" ") +tree.write(output_xml, encoding="utf-8", xml_declaration=True) +output_txt.write_text(raw) diff --git a/.github/scripts/android/convert_instrumentation_tree.sh b/.github/scripts/android/convert_instrumentation_tree.sh new file mode 100644 index 0000000..9ffa4b9 --- /dev/null +++ b/.github/scripts/android/convert_instrumentation_tree.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +results_root_dir="${RESULTS_ROOT_DIR:-android-test-results}" +emulator_suite_name="${EMULATOR_SUITE_NAME:-androidTest}" +overall_exit_code=0 + +if [[ ! -d "$results_root_dir" ]]; then + echo "Results directory does not exist: $results_root_dir" + exit 1 +fi + +raw_files="$(find "$results_root_dir" -name 'instrumentation-raw.txt' | sort)" +if [[ -z "$raw_files" ]]; then + echo "No instrumentation-raw.txt files found in $results_root_dir" + exit 1 +fi + +while IFS= read -r raw_file; do + result_dir="$(dirname "$raw_file")" + build_name="$(basename "$result_dir")" + python3 .github/scripts/android/convert_instrumentation_to_junit.py \ + "$raw_file" \ + "$result_dir/instrumentation-results.xml" \ + "$result_dir/instrumentation.txt" \ + "${emulator_suite_name}-${build_name}" + + if rg -q 'INSTRUMENTATION_STATUS_CODE: -2|INSTRUMENTATION_FAILED:|FAILURES!!!' "$raw_file"; then + echo "Detected instrumentation failure markers in $raw_file" + overall_exit_code=1 + fi + + if rg -q 'tests="0"' "$result_dir/instrumentation-results.xml"; then + echo "Detected zero executed tests in $result_dir/instrumentation-results.xml" + overall_exit_code=1 + fi +done <<< "$raw_files" + +exit "$overall_exit_code" diff --git a/.github/scripts/android/enable_kvm_if_available.sh b/.github/scripts/android/enable_kvm_if_available.sh new file mode 100644 index 0000000..7290aee --- /dev/null +++ b/.github/scripts/android/enable_kvm_if_available.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ -e /dev/kvm ]]; then + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ + | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm +else + echo "/dev/kvm is not available on this runner" +fi diff --git a/.github/scripts/android/install_system_image_with_retry.sh b/.github/scripts/android/install_system_image_with_retry.sh new file mode 100644 index 0000000..c1f7ae6 --- /dev/null +++ b/.github/scripts/android/install_system_image_with_retry.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +system_image_package="${ANDROID_SYSTEM_IMAGE_PACKAGE:?}" +sdk_root="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}" + +if [[ -z "$sdk_root" ]]; then + echo "ANDROID_SDK_ROOT or ANDROID_HOME must be set" + exit 1 +fi + +find_sdkmanager() { + if command -v sdkmanager >/dev/null 2>&1; then + command -v sdkmanager + return 0 + fi + + local candidate + for candidate in \ + "$sdk_root/cmdline-tools/latest/bin/sdkmanager" \ + "$sdk_root/cmdline-tools/bin/sdkmanager" \ + "$sdk_root/tools/bin/sdkmanager" \ + "/usr/local/lib/android/sdk/cmdline-tools/latest/bin/sdkmanager" \ + "/usr/local/lib/android/sdk/cmdline-tools/bin/sdkmanager" + do + if [[ -x "$candidate" ]]; then + echo "$candidate" + return 0 + fi + done + + return 1 +} + +sdkmanager_bin="$(find_sdkmanager || true)" +if [[ -z "$sdkmanager_bin" ]]; then + echo "sdkmanager executable was not found" + exit 1 +fi +cleanup_partial_downloads() { + rm -rf "$HOME/.android/cache"/* || true + rm -rf "$sdk_root"/.android/cache/* || true + rm -rf "$sdk_root"/temp/* || true +} + +attempt=1 +while [[ "$attempt" -le 3 ]]; do + echo "Installing Android system image ($system_image_package), attempt $attempt/3" + if "$sdkmanager_bin" --install "$system_image_package" --channel=0; then + exit 0 + fi + + echo "System image installation failed on attempt $attempt" + cleanup_partial_downloads + sleep 5 + attempt=$((attempt + 1)) +done + +echo "Failed to install Android system image after retries: $system_image_package" +exit 1 diff --git a/.github/scripts/android/run_all_instrumentation_variants.sh b/.github/scripts/android/run_all_instrumentation_variants.sh new file mode 100644 index 0000000..7c95123 --- /dev/null +++ b/.github/scripts/android/run_all_instrumentation_variants.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +set -euo pipefail + +apk_root_dir="${APK_ROOT_DIR:?}" +results_root_dir="${RESULTS_ROOT_DIR:-android-test-results}" +app_package="${APP_PACKAGE:-com.itlab.notes}" +test_package="${TEST_PACKAGE:-com.itlab.notes.test}" +instrumentation_runner="${INSTRUMENTATION_RUNNER:-com.itlab.notes.test/androidx.test.runner.AndroidJUnitRunner}" +export ANDROID_SERIAL="${ANDROID_SERIAL:-emulator-5554}" + +adb_retry() { + local attempt=1 + while [[ "$attempt" -le 5 ]]; do + if adb "$@"; then + return 0 + fi + + echo "adb command failed on attempt $attempt: adb $*" + sleep 5 + adb start-server || true + adb wait-for-device || true + attempt=$((attempt + 1)) + done + + adb "$@" +} + +package_installed() { + local package_name="$1" + adb shell pm path "$package_name" >/dev/null 2>&1 +} + +wait_for_boot_completed() { + local attempt=1 + while [[ "$attempt" -le 24 ]]; do + if adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' | grep -q '^1$'; then + return 0 + fi + + echo "Waiting for sys.boot_completed (attempt $attempt/24)" + sleep 5 + adb wait-for-device || true + attempt=$((attempt + 1)) + done + + echo "Timed out waiting for sys.boot_completed" + adb shell getprop sys.boot_completed || true + return 1 +} + +install_and_run() { + local build_dir="$1" + local build_name="$2" + local result_dir="$results_root_dir/$build_name" + local app_apk + local test_apk + local instrumentation_exit_code=0 + + mkdir -p "$result_dir" + + app_apk="$(find "$build_dir" -name 'app-debug.apk' | head -n 1)" + test_apk="$(find "$build_dir" -name 'app-debug-androidTest.apk' | head -n 1)" + + if [[ -z "$app_apk" || -z "$test_apk" ]]; then + echo "Missing APK artifacts in $build_dir" + return 1 + fi + + if package_installed "$test_package"; then + adb shell pm clear "$test_package" >/dev/null 2>&1 || true + adb uninstall "$test_package" >/dev/null 2>&1 || true + fi + + if package_installed "$app_package"; then + adb shell pm clear "$app_package" >/dev/null 2>&1 || true + adb uninstall "$app_package" >/dev/null 2>&1 || true + fi + + adb_retry logcat -c + adb_retry install -r "$app_apk" + adb_retry install -r "$test_apk" + + set +e + adb_retry shell am instrument -w "$instrumentation_runner" | tee "$result_dir/instrumentation-raw.txt" + instrumentation_exit_code=$? + set -e + + adb logcat -d > "$result_dir/logcat.txt" || true + + if package_installed "$test_package"; then + adb uninstall "$test_package" >/dev/null 2>&1 || true + fi + + if package_installed "$app_package"; then + adb uninstall "$app_package" >/dev/null 2>&1 || true + fi + + return "$instrumentation_exit_code" +} + +adb start-server +adb wait-for-device +wait_for_boot_completed +adb shell input keyevent 82 || true +adb_retry shell settings put global window_animation_scale 0 || true +adb_retry shell settings put global transition_animation_scale 0 || true +adb_retry shell settings put global animator_duration_scale 0 || true + +mkdir -p "$results_root_dir" + +mapfile -t build_dirs < <(find "$apk_root_dir" -mindepth 1 -maxdepth 1 -type d | sort) +if [[ "${#build_dirs[@]}" -eq 0 ]]; then + echo "No build artifact directories were found in $apk_root_dir" + exit 1 +fi + +overall_exit_code=0 +for build_dir in "${build_dirs[@]}"; do + build_name="$(basename "$build_dir")" + echo "Running instrumentation for $build_name" + if ! install_and_run "$build_dir" "$build_name"; then + overall_exit_code=1 + fi +done + +exit "$overall_exit_code" diff --git a/.github/scripts/android/run_emulator_instrumentation.sh b/.github/scripts/android/run_emulator_instrumentation.sh new file mode 100644 index 0000000..120b38c --- /dev/null +++ b/.github/scripts/android/run_emulator_instrumentation.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +set -euo pipefail + +apk_dir="${APK_DIR:?}" +export ANDROID_SERIAL="${ANDROID_SERIAL:-emulator-5554}" + +app_apk="$(find "$apk_dir" -name 'app-debug.apk' | head -n 1)" +test_apk="$(find "$apk_dir" -name 'app-debug-androidTest.apk' | head -n 1)" + +if [[ -z "$app_apk" || -z "$test_apk" ]]; then + echo "Missing APK artifacts in $apk_dir" + exit 1 +fi + +adb_retry() { + local attempt=1 + while [[ "$attempt" -le 5 ]]; do + if adb "$@"; then + return 0 + fi + + echo "adb command failed on attempt $attempt: adb $*" + sleep 5 + adb start-server || true + adb wait-for-device || true + attempt=$((attempt + 1)) + done + + adb "$@" +} + +wait_for_boot_completed() { + local attempt=1 + while [[ "$attempt" -le 24 ]]; do + if adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' | grep -q '^1$'; then + return 0 + fi + + echo "Waiting for sys.boot_completed (attempt $attempt/24)" + sleep 5 + adb wait-for-device || true + attempt=$((attempt + 1)) + done + + echo "Timed out waiting for sys.boot_completed" + adb shell getprop sys.boot_completed || true + return 1 +} + +adb start-server +adb wait-for-device +wait_for_boot_completed +adb shell input keyevent 82 || true +adb_retry shell settings put global window_animation_scale 0 || true +adb_retry shell settings put global transition_animation_scale 0 || true +adb_retry shell settings put global animator_duration_scale 0 || true +adb_retry logcat -c +adb_retry install -r "$app_apk" +adb_retry install -r "$test_apk" + +set +e +adb_retry shell am instrument -w com.itlab.notes.test/androidx.test.runner.AndroidJUnitRunner | tee instrumentation-raw.txt +instrumentation_exit_code=$? +set -e + +adb logcat -d > logcat.txt || true +exit "$instrumentation_exit_code" diff --git a/.github/scripts/android/validate_debug_apk_tasks.sh b/.github/scripts/android/validate_debug_apk_tasks.sh new file mode 100644 index 0000000..9f7e718 --- /dev/null +++ b/.github/scripts/android/validate_debug_apk_tasks.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + app:assembleDebug \ + app:assembleDebugAndroidTest \ + -m \ + --stacktrace diff --git a/.github/scripts/codeql/build_for_codeql.sh b/.github/scripts/codeql/build_for_codeql.sh new file mode 100644 index 0000000..49f5ef5 --- /dev/null +++ b/.github/scripts/codeql/build_for_codeql.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + clean \ + ai:assembleDebug \ + app:assembleDebug \ + data:assembleDebug \ + domain:assembleDebug \ + --no-build-cache \ + --rerun-tasks \ + --stacktrace diff --git a/.github/scripts/pr/build_pr_summary.py b/.github/scripts/pr/build_pr_summary.py new file mode 100644 index 0000000..f62a22c --- /dev/null +++ b/.github/scripts/pr/build_pr_summary.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import json +import sys +import xml.etree.ElementTree as ET +from pathlib import Path + + +def sum_junit_metrics(files: list[Path]) -> dict[str, int]: + totals = {"tests": 0, "failures": 0, "errors": 0, "skipped": 0} + for file in files: + try: + root = ET.parse(file).getroot() + except ET.ParseError: + continue + + if root.tag == "testsuites": + suites = list(root.findall("testsuite")) + elif root.tag == "testsuite": + suites = [root] + else: + suites = [] + + for suite in suites: + for key in totals: + totals[key] += int(suite.attrib.get(key, "0")) + + return totals + + +def count_lint_issues(files: list[Path]) -> int: + count = 0 + for file in files: + try: + root = ET.parse(file).getroot() + except ET.ParseError: + continue + count += len(root.findall(".//issue")) + return count + + +def count_ktlint_issues(files: list[Path]) -> int: + count = 0 + for file in files: + try: + root = ET.parse(file).getroot() + except ET.ParseError: + continue + count += len(root.findall(".//error")) + return count + + +def count_sarif_results(files: list[Path]) -> int: + count = 0 + for file in files: + try: + data = json.loads(file.read_text()) + except Exception: + continue + for run in data.get("runs", []): + count += len(run.get("results", [])) + return count + + +def aggregate_line_coverage(files: list[Path]) -> tuple[int, int]: + covered = 0 + missed = 0 + for file in files: + try: + root = ET.parse(file).getroot() + except ET.ParseError: + continue + + for counter in root.findall("./counter"): + if counter.attrib.get("type") == "LINE": + covered += int(counter.attrib.get("covered", "0")) + missed += int(counter.attrib.get("missed", "0")) + break + return covered, missed + + +def format_test_line(label: str, metrics: dict[str, int]) -> str: + total_failures = metrics["failures"] + metrics["errors"] + status = "PASS" if total_failures == 0 else "FAIL" + return ( + f"- {label}: {status} " + f"({metrics['tests']} tests, {total_failures} failed, {metrics['skipped']} skipped)" + ) + + +def main() -> int: + if len(sys.argv) != 7: + print( + "usage: build_pr_summary.py ", + file=sys.stderr, + ) + return 2 + + artifacts_dir = Path(sys.argv[1]) + output_file = Path(sys.argv[2]) + + unit_xml = sorted(artifacts_dir.glob("**/build/test-results/**/*.xml")) + instrumentation_xml = sorted(artifacts_dir.glob("**/instrumentation-results.xml")) + lint_xml = sorted(artifacts_dir.glob("**/build/reports/lint-results-*.xml")) + ktlint_xml = sorted(artifacts_dir.glob("**/build/reports/ktlint/**/*.xml")) + kover_xml = sorted(artifacts_dir.glob("**/build/reports/kover/**/*.xml")) + detekt_sarif = sorted(artifacts_dir.glob("**/build/reports/detekt/*.sarif")) + gitleaks_sarif = sorted(artifacts_dir.glob("**/build/reports/gitleaks/*.sarif")) + + unit_metrics = sum_junit_metrics(unit_xml) + instrumentation_metrics = sum_junit_metrics(instrumentation_xml) + lint_issues = count_lint_issues(lint_xml) + ktlint_issues = count_ktlint_issues(ktlint_xml) + detekt_findings = count_sarif_results(detekt_sarif) + gitleaks_findings = count_sarif_results(gitleaks_sarif) + covered, missed = aggregate_line_coverage(kover_xml) + total_lines = covered + missed + coverage = (covered / total_lines * 100.0) if total_lines else None + + pr_number = sys.argv[3] + head_sha = sys.argv[4] + run_url = sys.argv[5] + ci_conclusion = sys.argv[6] + + lines = [ + "## CI Quality Overview", + "", + f"- CI conclusion: `{ci_conclusion or 'unknown'}`", + f"- Head SHA: `{head_sha[:12]}`" if head_sha else None, + f"- PR: `#{pr_number}`" if pr_number else None, + f"- Workflow run: [view run]({run_url})" if run_url else None, + "", + "### Tests", + format_test_line("Unit", unit_metrics) if unit_xml else "- Unit: no XML reports found", + ( + format_test_line("Instrumentation", instrumentation_metrics) + if instrumentation_xml + else "- Instrumentation: no XML reports found" + ), + "", + "### Static Analysis", + f"- Android Lint: {lint_issues} issue(s) from XML reports" if lint_xml else "- Android Lint: no XML reports found", + f"- ktlint: {ktlint_issues} issue(s) from XML reports" if ktlint_xml else "- ktlint: no XML reports found", + f"- detekt: {detekt_findings} finding(s) uploaded via SARIF" if detekt_sarif else "- detekt: no SARIF reports found", + f"- gitleaks: {gitleaks_findings} finding(s) uploaded via SARIF" if gitleaks_sarif else "- gitleaks: no SARIF reports found", + "- CodeQL: see the Code Scanning section in this PR", + "", + "### Coverage", + ( + f"- Line coverage: {coverage:.2f}% ({covered} covered / {total_lines} total)" + if coverage is not None + else "- Line coverage: no Kover XML reports found" + ), + ] + + output_file.write_text("\n".join(line for line in lines if line is not None) + "\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/.github/scripts/pr/list_downloaded_artifacts.sh b/.github/scripts/pr/list_downloaded_artifacts.sh new file mode 100644 index 0000000..4951d12 --- /dev/null +++ b/.github/scripts/pr/list_downloaded_artifacts.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail + +find "${1:-pr-artifacts}" -maxdepth 4 -type f | sort diff --git a/.github/scripts/preflight/classify_changes.sh b/.github/scripts/preflight/classify_changes.sh new file mode 100644 index 0000000..284a880 --- /dev/null +++ b/.github/scripts/preflight/classify_changes.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -euo pipefail + +event_name="${EVENT_NAME:?}" +current_sha="${CURRENT_SHA:?}" +github_output="${GITHUB_OUTPUT:?}" + +if [[ "$event_name" == "pull_request" ]]; then + base_sha="${BASE_SHA:?}" + head_sha="${HEAD_SHA:?}" + changed="$(git diff --name-only "$base_sha" "$head_sha")" +elif [[ -n "${BEFORE_SHA:-}" && "${BEFORE_SHA}" != "0000000000000000000000000000000000000000" ]]; then + changed="$(git diff --name-only "$BEFORE_SHA" "$current_sha")" +else + changed="$(git show --name-only --pretty='' "$current_sha")" +fi + +clean_changed="$(printf '%s\n' "$changed" | sed '/^$/d')" +kotlin_version="$(sed -nE 's/^kotlin = "([^"]+)"/\1/p' gradle/libs.versions.toml | head -n1)" +codeql_supported_kotlin="true" + +if [[ -n "$kotlin_version" ]]; then + highest_kotlin="$(printf '%s\n%s\n' "$kotlin_version" "2.3.20" | sort -V | tail -n1)" + if [[ "$highest_kotlin" == "$kotlin_version" ]]; then + codeql_supported_kotlin="false" + fi +fi + +if [[ "$event_name" == "pull_request" ]]; then + run_android_tests="true" + run_release="true" + run_codeql="$codeql_supported_kotlin" +else + if printf '%s\n' "$clean_changed" | grep -E '^(app/|ai/|.*/src/androidTest/|.*/src/main/|build.gradle.kts|settings.gradle.kts|gradle/|.github/workflows/)' >/dev/null; then + run_android_tests="true" + run_release="true" + else + run_android_tests="false" + run_release="false" + fi + + if printf '%s\n' "$clean_changed" | grep -E '^(app/|ai/|data/|domain/|build.gradle.kts|settings.gradle.kts|gradle/|.github/workflows/)' >/dev/null; then + run_codeql="$codeql_supported_kotlin" + else + run_codeql="false" + fi +fi + +{ + echo "run_android_tests=$run_android_tests" + echo "run_release=$run_release" + echo "run_codeql=$run_codeql" + echo "changed_paths<<__EOF__" + if [[ -n "$clean_changed" ]]; then + printf '%s\n' "$clean_changed" + fi + echo "__EOF__" +} >> "$github_output" diff --git a/.github/scripts/preflight/write_summary.sh b/.github/scripts/preflight/write_summary.sh new file mode 100644 index 0000000..ea371e8 --- /dev/null +++ b/.github/scripts/preflight/write_summary.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +changed_paths="${CHANGED_PATHS:-}" +file_count="$(printf '%s\n' "$changed_paths" | sed '/^$/d' | wc -l | tr -d ' ')" + +{ + echo "## Preflight" + echo + echo "- Event: \`${EVENT_NAME:?}\`" + echo "- Changed files: \`${file_count}\`" + echo "- Run release: \`${RUN_RELEASE:?}\`" + echo "- Run CodeQL: \`${RUN_CODEQL:?}\`" + echo "- Run Android tests: \`${RUN_ANDROID_TESTS:?}\`" + echo + echo "### Changed Paths" + echo '```text' + if [[ -n "$changed_paths" ]]; then + printf '%s\n' "$changed_paths" + else + echo "(none)" + fi + echo '```' +} >> "${GITHUB_STEP_SUMMARY:?}" diff --git a/.github/scripts/quality/run_coverage.sh b/.github/scripts/quality/run_coverage.sh new file mode 100644 index 0000000..5102513 --- /dev/null +++ b/.github/scripts/quality/run_coverage.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + ai:testDebugUnitTest \ + app:testDebugUnitTest \ + data:testDebugUnitTest \ + domain:testDebugUnitTest \ + koverXmlReport \ + koverVerify \ + --stacktrace diff --git a/.github/scripts/quality/run_debug_build_and_unit_tests.sh b/.github/scripts/quality/run_debug_build_and_unit_tests.sh new file mode 100644 index 0000000..fb3e693 --- /dev/null +++ b/.github/scripts/quality/run_debug_build_and_unit_tests.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + ai:assembleDebug \ + app:assembleDebug \ + app:assembleDebugAndroidTest \ + data:assembleDebug \ + domain:assembleDebug \ + ai:testDebugUnitTest \ + app:testDebugUnitTest \ + data:testDebugUnitTest \ + domain:testDebugUnitTest \ + --stacktrace diff --git a/.github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1 b/.github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1 new file mode 100644 index 0000000..4e750d7 --- /dev/null +++ b/.github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1 @@ -0,0 +1,18 @@ +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +& .\gradlew.bat ` + ai:assembleDebug ` + app:assembleDebug ` + app:assembleDebugAndroidTest ` + data:assembleDebug ` + domain:assembleDebug ` + ai:testDebugUnitTest ` + app:testDebugUnitTest ` + data:testDebugUnitTest ` + domain:testDebugUnitTest ` + --stacktrace + +if ($LASTEXITCODE -ne 0) { + throw "Gradle debug build and unit tests failed with exit code $LASTEXITCODE." +} diff --git a/.github/scripts/quality/run_foundation.sh b/.github/scripts/quality/run_foundation.sh new file mode 100644 index 0000000..4ced4eb --- /dev/null +++ b/.github/scripts/quality/run_foundation.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + ktlintCheck \ + detekt \ + ai:lintDebug \ + app:lintDebug \ + data:lintDebug \ + domain:lintDebug \ + --stacktrace diff --git a/.github/scripts/quality/write_coverage_summary.sh b/.github/scripts/quality/write_coverage_summary.sh new file mode 100644 index 0000000..ea3bbd3 --- /dev/null +++ b/.github/scripts/quality/write_coverage_summary.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +{ + echo "## Coverage" + echo + echo "Kover XML report generated at \`build/reports/kover/report.xml\`" + echo "Coverage artifacts are attached to this workflow run." +} >> "${GITHUB_STEP_SUMMARY:?}" diff --git a/.github/scripts/quality/write_foundation_summary.sh b/.github/scripts/quality/write_foundation_summary.sh new file mode 100644 index 0000000..5dd8285 --- /dev/null +++ b/.github/scripts/quality/write_foundation_summary.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +{ + echo "## Quality Foundation" + echo + echo "- ktlint, detekt, and Android lint executed" + echo "- Detekt findings are uploaded to Code Scanning" + echo "- Lint XML/HTML reports are attached as workflow artifacts" +} >> "${GITHUB_STEP_SUMMARY:?}" diff --git a/.github/scripts/release/assemble_release.sh b/.github/scripts/release/assemble_release.sh new file mode 100644 index 0000000..60ccc0d --- /dev/null +++ b/.github/scripts/release/assemble_release.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + ai:assembleRelease \ + app:assembleRelease \ + data:assembleRelease \ + domain:assembleRelease \ + --stacktrace diff --git a/.github/scripts/release/lint_release.sh b/.github/scripts/release/lint_release.sh new file mode 100644 index 0000000..18e9d14 --- /dev/null +++ b/.github/scripts/release/lint_release.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +./gradlew \ + ai:lintRelease \ + app:lintRelease \ + data:lintRelease \ + domain:lintRelease \ + --stacktrace diff --git a/.github/scripts/security/run_gitleaks.sh b/.github/scripts/security/run_gitleaks.sh new file mode 100644 index 0000000..def0ed2 --- /dev/null +++ b/.github/scripts/security/run_gitleaks.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +mkdir -p build/reports/gitleaks +curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz" \ + | tar -xz gitleaks +./gitleaks detect \ + --source . \ + --report-format sarif \ + --report-path build/reports/gitleaks/gitleaks.sarif \ + --redact diff --git a/.github/scripts/setup/install_android_sdk_packages.sh b/.github/scripts/setup/install_android_sdk_packages.sh new file mode 100644 index 0000000..981c6b5 --- /dev/null +++ b/.github/scripts/setup/install_android_sdk_packages.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +set +o pipefail +yes | sdkmanager --licenses >/dev/null +set -o pipefail + +packages=( + "build-tools;${ANDROID_BUILD_TOOLS:?}" +) + +platform_package="platforms;android-${ANDROID_API_LEVEL:?}" +sdk_packages="$(sdkmanager --list)" +if ! grep -Fq "${platform_package}" <<<"${sdk_packages}"; then + fallback_platform_package="${platform_package}.0" + if grep -Fq "${fallback_platform_package}" <<<"${sdk_packages}"; then + platform_package="${fallback_platform_package}" + fi +fi + +packages=("${platform_package}" "${packages[@]}") + +if [[ "${INSTALL_SYSTEM_IMAGE:-false}" == "true" && -n "${ANDROID_SYSTEM_IMAGE:-}" ]]; then + packages+=("emulator") + packages+=("${ANDROID_SYSTEM_IMAGE}") +fi + +sdkmanager "${packages[@]}" diff --git a/.github/scripts/setup/install_android_sdk_packages_windows.ps1 b/.github/scripts/setup/install_android_sdk_packages_windows.ps1 new file mode 100644 index 0000000..f9bbe32 --- /dev/null +++ b/.github/scripts/setup/install_android_sdk_packages_windows.ps1 @@ -0,0 +1,48 @@ +Set-StrictMode -Version Latest +$ErrorActionPreference = "Stop" + +function Get-SdkManagerPath { + $candidates = @( + (Join-Path $env:ANDROID_SDK_ROOT "cmdline-tools\latest\bin\sdkmanager.bat"), + (Join-Path $env:ANDROID_HOME "cmdline-tools\latest\bin\sdkmanager.bat") + ) + + foreach ($candidate in $candidates) { + if ($candidate -and (Test-Path $candidate)) { + return $candidate + } + } + + $command = Get-Command sdkmanager.bat -ErrorAction SilentlyContinue + if ($command) { + return $command.Source + } + + throw "sdkmanager.bat was not found in ANDROID_SDK_ROOT, ANDROID_HOME, or PATH." +} + +$sdkmanager = Get-SdkManagerPath + +$platformPackage = "platforms;android-$env:ANDROID_API_LEVEL" +$sdkPackages = & $sdkmanager --list +if ($sdkPackages -notmatch [regex]::Escape($platformPackage)) { + $fallbackPlatformPackage = "$platformPackage.0" + if ($sdkPackages -match [regex]::Escape($fallbackPlatformPackage)) { + $platformPackage = $fallbackPlatformPackage + } +} + +$packages = @( + $platformPackage, + "build-tools;$env:ANDROID_BUILD_TOOLS" +) + +if ($env:INSTALL_SYSTEM_IMAGE -eq "true" -and -not [string]::IsNullOrWhiteSpace($env:ANDROID_SYSTEM_IMAGE)) { + $packages += "emulator" + $packages += $env:ANDROID_SYSTEM_IMAGE +} + +$licenseAnswers = 1..20 | ForEach-Object { "y" } +$licenseAnswers | & $sdkmanager --licenses *> $null + +& $sdkmanager @packages diff --git a/.github/workflows/android-tests.yml b/.github/workflows/android-tests.yml new file mode 100644 index 0000000..9979e0c --- /dev/null +++ b/.github/workflows/android-tests.yml @@ -0,0 +1,109 @@ +name: Android Tests + +on: + workflow_call: + +env: + ANDROID_API_LEVEL: "37.0" + ANDROID_BUILD_TOOLS: "37.0.0" + JAVA_VERSION: "21" + +jobs: + emulator-validation: + name: Emulator Validation + runs-on: ubuntu-24.04 + timeout-minutes: 20 + permissions: + contents: read + checks: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Validate debug APK tasks + shell: bash + run: bash .github/scripts/android/validate_debug_apk_tasks.sh + + android-tests: + name: Android Tests (${{ matrix.emulator_name }}) + needs: emulator-validation + strategy: + fail-fast: false + max-parallel: 2 + matrix: + include: + - emulator_name: x86_64 + runs_on: ubuntu-24.04 + api_level: 34 + target: default + arch: x86_64 + profile: pixel_7 + emulator_options: -no-snapshot-save -no-window -noaudio -no-boot-anim -gpu swiftshader_indirect -camera-back none -camera-front none + test_suffix: x86 + suite_name: emulator-x86_64 + runs-on: ${{ matrix.runs_on }} + timeout-minutes: 45 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Download build artifacts + uses: actions/download-artifact@v8.0.1 + with: + pattern: debug-apks-* + path: build-artifacts + + - name: Enable KVM when available + if: runner.os == 'Linux' + shell: bash + run: bash .github/scripts/android/enable_kvm_if_available.sh + + - name: Preinstall emulator system image + shell: bash + env: + ANDROID_SYSTEM_IMAGE_PACKAGE: system-images;android-${{ matrix.api_level }};${{ matrix.target }};${{ matrix.arch }} + run: bash .github/scripts/android/install_system_image_with_retry.sh + + - name: Run instrumentation on emulator + uses: reactivecircus/android-emulator-runner@v2.37.0 + with: + api-level: ${{ matrix.api_level }} + target: ${{ matrix.target }} + arch: ${{ matrix.arch }} + profile: ${{ matrix.profile }} + disable-animations: true + emulator-boot-timeout: 900 + emulator-options: ${{ matrix.emulator_options }} + script: bash .github/scripts/android/run_all_instrumentation_variants.sh + env: + APK_ROOT_DIR: build-artifacts + RESULTS_ROOT_DIR: android-test-results + ANDROID_SERIAL: emulator-5554 + + - name: Convert instrumentation output to JUnit + if: always() + shell: bash + env: + RESULTS_ROOT_DIR: android-test-results + EMULATOR_SUITE_NAME: ${{ matrix.suite_name }} + run: bash .github/scripts/android/convert_instrumentation_tree.sh + + - name: Upload android test artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: android-test-reports-${{ matrix.test_suffix }} + if-no-files-found: ignore + path: | + emulator.log + android-test-results/** diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2df398c..8a491ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: pull_request: + merge_group: push: branches: - main @@ -13,340 +14,71 @@ concurrency: group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true -env: - ANDROID_API_LEVEL: "36" - ANDROID_BUILD_TOOLS: "36.0.0" - ANDROID_SDK_ROOT: /usr/local/lib/android/sdk - JAVA_VERSION: "17" - jobs: - detect-gradle: - name: Detect Gradle Project - runs-on: ubuntu-latest + preflight: + name: Preflight + uses: ./.github/workflows/preflight.yml permissions: contents: read - outputs: - has_gradle: ${{ steps.detect.outputs.has_gradle }} - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Detect Gradle files - id: detect - shell: bash - run: | - if [ -f gradlew ] || [ -f build.gradle.kts ] || [ -f build.gradle ] || [ -f settings.gradle.kts ] || [ -f settings.gradle ]; then - echo "has_gradle=true" >> "$GITHUB_OUTPUT" - else - echo "has_gradle=false" >> "$GITHUB_OUTPUT" - fi - quality: - name: Quality - needs: detect-gradle - if: needs.detect-gradle.outputs.has_gradle == 'true' - runs-on: ubuntu-latest + dependency-review: + name: Dependency Review + needs: preflight + if: github.event_name == 'pull_request' + uses: ./.github/workflows/supply-chain.yml permissions: contents: read - security-events: write - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: gradle - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v5 - - - name: Install Android SDK packages - shell: bash - run: | - SDKMANAGER="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" - if [ ! -x "${SDKMANAGER}" ]; then - SDKMANAGER="$(command -v sdkmanager)" - fi - - set +o pipefail - yes | "${SDKMANAGER}" --licenses >/dev/null - set -o pipefail - "${SDKMANAGER}" "platforms;android-${ANDROID_API_LEVEL}" "build-tools;${ANDROID_BUILD_TOOLS}" - - - name: Quality gates - run: | - ./gradlew \ - ai:assembleDebug \ - app:assembleDebug \ - data:assembleDebug \ - domain:assembleDebug \ - ktlintCheck \ - detekt \ - ai:lintDebug \ - app:lintDebug \ - data:lintDebug \ - domain:lintDebug \ - ai:testDebugUnitTest \ - app:testDebugUnitTest \ - data:testDebugUnitTest \ - domain:testDebugUnitTest \ - koverXmlReport \ - koverVerify \ - --stacktrace - - - name: Upload detekt SARIF for ai - if: always() && hashFiles('ai/build/reports/detekt/detekt.sarif') != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: ai/build/reports/detekt/detekt.sarif - category: detekt-ai - - - name: Upload detekt SARIF for app - if: always() && hashFiles('app/build/reports/detekt/detekt.sarif') != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: app/build/reports/detekt/detekt.sarif - category: detekt-app - - - name: Upload detekt SARIF for data - if: always() && hashFiles('data/build/reports/detekt/detekt.sarif') != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: data/build/reports/detekt/detekt.sarif - category: detekt-data - - - name: Upload detekt SARIF for domain - if: always() && hashFiles('domain/build/reports/detekt/detekt.sarif') != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: domain/build/reports/detekt/detekt.sarif - category: detekt-domain - - - name: Upload quality artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - name: quality-reports - if-no-files-found: ignore - path: | - **/build/reports/kover/** - **/build/reports/detekt/** - **/build/reports/ktlint/** - **/build/reports/lint-results-*.html - **/build/reports/lint-results-*.xml + pull-requests: read secrets: name: Secrets - runs-on: ubuntu-latest + needs: preflight + uses: ./.github/workflows/security.yml permissions: contents: read security-events: write - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Run gitleaks - shell: bash - run: | - mkdir -p build/reports/gitleaks - curl -sSL "https://github.com/gitleaks/gitleaks/releases/download/v8.30.0/gitleaks_8.30.0_linux_x64.tar.gz" \ - | tar -xz gitleaks - ./gitleaks detect \ - --source . \ - --report-format sarif \ - --report-path build/reports/gitleaks/gitleaks.sarif \ - --redact - - - name: Upload gitleaks SARIF - if: always() && hashFiles('build/reports/gitleaks/gitleaks.sarif') != '' - uses: github/codeql-action/upload-sarif@v4 - with: - sarif_file: build/reports/gitleaks/gitleaks.sarif - category: gitleaks - - name: Upload secrets artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - name: secret-reports - if-no-files-found: ignore - path: build/reports/gitleaks/** + build-quality: + name: Build Quality + needs: preflight + uses: ./.github/workflows/quality.yml + permissions: + contents: read + checks: write + pull-requests: write + security-events: write codeql: name: CodeQL - needs: detect-gradle - if: needs.detect-gradle.outputs.has_gradle == 'true' - runs-on: ubuntu-latest + needs: + - preflight + - build-quality + - secrets + if: needs.preflight.outputs.run_codeql == 'true' + uses: ./.github/workflows/codeql.yml permissions: actions: read contents: read security-events: write - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: gradle - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v5 - - - name: Install Android SDK packages - shell: bash - run: | - SDKMANAGER="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" - if [ ! -x "${SDKMANAGER}" ]; then - SDKMANAGER="$(command -v sdkmanager)" - fi - - set +o pipefail - yes | "${SDKMANAGER}" --licenses >/dev/null - set -o pipefail - "${SDKMANAGER}" "platforms;android-${ANDROID_API_LEVEL}" "build-tools;${ANDROID_BUILD_TOOLS}" - - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: java-kotlin - build-mode: manual - - - name: Build for CodeQL - run: | - ./gradlew \ - ai:assembleDebug \ - app:assembleDebug \ - data:assembleDebug \ - domain:assembleDebug \ - --stacktrace - - - name: Analyze - uses: github/codeql-action/analyze@v4 release: name: Release - needs: detect-gradle - if: needs.detect-gradle.outputs.has_gradle == 'true' - runs-on: ubuntu-latest + needs: + - preflight + - build-quality + if: needs.preflight.outputs.run_release == 'true' + uses: ./.github/workflows/release.yml permissions: contents: read - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: gradle - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v5 - - - name: Install Android SDK packages - shell: bash - run: | - SDKMANAGER="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" - if [ ! -x "${SDKMANAGER}" ]; then - SDKMANAGER="$(command -v sdkmanager)" - fi - - set +o pipefail - yes | "${SDKMANAGER}" --licenses >/dev/null - set -o pipefail - "${SDKMANAGER}" "platforms;android-${ANDROID_API_LEVEL}" "build-tools;${ANDROID_BUILD_TOOLS}" - - - name: Release checks - run: | - ./gradlew \ - ai:assembleRelease \ - app:assembleRelease \ - data:assembleRelease \ - domain:assembleRelease \ - ai:lintRelease \ - app:lintRelease \ - data:lintRelease \ - domain:lintRelease \ - --stacktrace - - - name: Upload release artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - name: release-reports - if-no-files-found: ignore - path: | - **/build/reports/lint-results-*.html - **/build/reports/lint-results-*.xml android-tests: name: Android Tests - needs: detect-gradle - if: needs.detect-gradle.outputs.has_gradle == 'true' - runs-on: ubuntu-latest - timeout-minutes: 45 + needs: + - preflight + - build-quality + if: needs.preflight.outputs.run_android_tests == 'true' + uses: ./.github/workflows/android-tests.yml permissions: contents: read - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Set up Java - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: gradle - - - name: Set up Gradle - uses: gradle/actions/setup-gradle@v5 - - - name: Enable KVM - shell: bash - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ - | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - - - name: Install Android SDK packages - shell: bash - run: | - SDKMANAGER="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager" - if [ ! -x "${SDKMANAGER}" ]; then - SDKMANAGER="$(command -v sdkmanager)" - fi - - set +o pipefail - yes | "${SDKMANAGER}" --licenses >/dev/null - set -o pipefail - "${SDKMANAGER}" \ - "platforms;android-${ANDROID_API_LEVEL}" \ - "build-tools;${ANDROID_BUILD_TOOLS}" \ - "system-images;android-34;aosp_atd;x86_64" - - - name: Managed device tests - run: | - ./gradlew \ - app:pixel7api34DebugAndroidTest \ - -Pandroid.testoptions.manageddevices.emulator.gpu=swiftshader_indirect \ - --stacktrace - - - name: Upload android test artifacts - if: always() - uses: actions/upload-artifact@v7 - with: - name: android-test-reports - if-no-files-found: ignore - path: | - **/build/reports/androidTests/** - **/build/outputs/androidTest-results/** + checks: write + pull-requests: write diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..2cba8ad --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,42 @@ +name: CodeQL + +on: + workflow_call: + +env: + ANDROID_API_LEVEL: "37.0" + ANDROID_BUILD_TOOLS: "37.0.0" + JAVA_VERSION: "21" + +jobs: + codeql: + name: CodeQL + runs-on: ubuntu-24.04 + timeout-minutes: 30 + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4.34.1 + with: + languages: java-kotlin + build-mode: manual + + - name: Build for CodeQL + shell: bash + run: bash .github/scripts/codeql/build_for_codeql.sh + + - name: Analyze + uses: github/codeql-action/analyze@v4.34.1 diff --git a/.github/workflows/pr-report.yml b/.github/workflows/pr-report.yml new file mode 100644 index 0000000..9308c6b --- /dev/null +++ b/.github/workflows/pr-report.yml @@ -0,0 +1,98 @@ +name: PR Report + +on: + workflow_run: + workflows: + - CI + types: + - completed + +permissions: + actions: read + checks: write + contents: read + pull-requests: write + +jobs: + report: + name: Report Results To PR + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.pull_requests[0] != null && + github.event.workflow_run.conclusion != 'cancelled' + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Download workflow artifacts + uses: actions/download-artifact@v8.0.1 + with: + github-token: ${{ github.token }} + repository: ${{ github.repository }} + run-id: ${{ github.event.workflow_run.id }} + path: pr-artifacts + + - name: List downloaded artifacts + shell: bash + run: bash .github/scripts/pr/list_downloaded_artifacts.sh pr-artifacts + + - name: Publish unit test report + if: hashFiles('pr-artifacts/**/build/test-results/testDebugUnitTest/*.xml') != '' + continue-on-error: true + uses: mikepenz/action-junit-report@v6.3.1 + with: + commit: ${{ github.event.workflow_run.head_sha }} + pr_id: ${{ github.event.workflow_run.pull_requests[0].number }} + check_name: Unit Tests + report_paths: pr-artifacts/**/build/test-results/testDebugUnitTest/*.xml + require_tests: true + fail_on_failure: false + update_check: true + detailed_summary: true + + - name: Publish instrumentation report + if: hashFiles('pr-artifacts/**/instrumentation-results.xml') != '' + continue-on-error: true + uses: mikepenz/action-junit-report@v6.3.1 + with: + commit: ${{ github.event.workflow_run.head_sha }} + pr_id: ${{ github.event.workflow_run.pull_requests[0].number }} + check_name: Android Instrumentation + report_paths: pr-artifacts/**/instrumentation-results.xml + require_tests: true + fail_on_failure: false + update_check: true + detailed_summary: true + + - name: Publish coverage report + if: hashFiles('pr-artifacts/**/build/reports/kover/*.xml') != '' + continue-on-error: true + uses: madrapps/jacoco-report@v1.7.2 + with: + pr-number: ${{ github.event.workflow_run.pull_requests[0].number }} + paths: ${{ github.workspace }}/pr-artifacts/**/build/reports/kover/*.xml + token: ${{ github.token }} + min-coverage-overall: 60 + min-coverage-changed-files: 60 + title: Coverage + update-comment: true + comment-type: both + + - name: Build PR summary + shell: bash + run: | + python3 .github/scripts/pr/build_pr_summary.py \ + pr-artifacts \ + pr-summary.md \ + "${{ github.event.workflow_run.pull_requests[0].number }}" \ + "${{ github.event.workflow_run.head_sha }}" \ + "${{ github.event.workflow_run.html_url }}" \ + "${{ github.event.workflow_run.conclusion }}" + + - name: Publish sticky PR summary + uses: marocchino/sticky-pull-request-comment@v3.0.2 + with: + number: ${{ github.event.workflow_run.pull_requests[0].number }} + header: ci-quality-overview + path: pr-summary.md diff --git a/.github/workflows/preflight.yml b/.github/workflows/preflight.yml new file mode 100644 index 0000000..e986c79 --- /dev/null +++ b/.github/workflows/preflight.yml @@ -0,0 +1,65 @@ +name: Preflight + +on: + workflow_call: + outputs: + run_android_tests: + description: Whether Android managed-device tests should run + value: ${{ jobs.detect-changes.outputs.run_android_tests }} + run_release: + description: Whether release checks should run + value: ${{ jobs.detect-changes.outputs.run_release }} + run_codeql: + description: Whether CodeQL should run + value: ${{ jobs.detect-changes.outputs.run_codeql }} + changed_paths: + description: Newline-delimited changed paths + value: ${{ jobs.detect-changes.outputs.changed_paths }} + +jobs: + detect-changes: + name: Detect Changes + runs-on: ubuntu-24.04 + outputs: + run_android_tests: ${{ steps.classify.outputs.run_android_tests }} + run_release: ${{ steps.classify.outputs.run_release }} + run_codeql: ${{ steps.classify.outputs.run_codeql }} + changed_paths: ${{ steps.classify.outputs.changed_paths }} + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 + + - name: Classify changes + id: classify + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + BASE_SHA: ${{ github.event.pull_request.base.sha || '' }} + HEAD_SHA: ${{ github.event.pull_request.head.sha || '' }} + BEFORE_SHA: ${{ github.event.before || '' }} + CURRENT_SHA: ${{ github.sha }} + run: bash .github/scripts/preflight/classify_changes.sh + + preflight-summary: + name: Preflight + needs: detect-changes + runs-on: ubuntu-24.04 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Summarize preflight + shell: bash + env: + EVENT_NAME: ${{ github.event_name }} + RUN_RELEASE: ${{ needs.detect-changes.outputs.run_release }} + RUN_CODEQL: ${{ needs.detect-changes.outputs.run_codeql }} + RUN_ANDROID_TESTS: ${{ needs.detect-changes.outputs.run_android_tests }} + CHANGED_PATHS: ${{ needs.detect-changes.outputs.changed_paths }} + run: bash .github/scripts/preflight/write_summary.sh diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..171b33a --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,263 @@ +name: Quality + +on: + workflow_call: + +env: + ANDROID_API_LEVEL: "37.0" + ANDROID_BUILD_TOOLS: "37.0.0" + JAVA_VERSION: "21" + +jobs: + quality-foundation: + name: Quality Foundation + runs-on: ubuntu-24.04 + timeout-minutes: 25 + permissions: + contents: read + security-events: write + checks: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Format, static analysis, and lint + shell: bash + run: bash .github/scripts/quality/run_foundation.sh + + - name: Publish lint and static analysis summary + if: always() + shell: bash + run: bash .github/scripts/quality/write_foundation_summary.sh + + - name: Upload detekt SARIF for ai + if: always() && hashFiles('ai/build/reports/detekt/detekt.sarif') != '' + uses: github/codeql-action/upload-sarif@v4.34.1 + with: + sarif_file: ai/build/reports/detekt/detekt.sarif + category: detekt-ai + + - name: Upload detekt SARIF for app + if: always() && hashFiles('app/build/reports/detekt/detekt.sarif') != '' + uses: github/codeql-action/upload-sarif@v4.34.1 + with: + sarif_file: app/build/reports/detekt/detekt.sarif + category: detekt-app + + - name: Upload detekt SARIF for data + if: always() && hashFiles('data/build/reports/detekt/detekt.sarif') != '' + uses: github/codeql-action/upload-sarif@v4.34.1 + with: + sarif_file: data/build/reports/detekt/detekt.sarif + category: detekt-data + + - name: Upload detekt SARIF for domain + if: always() && hashFiles('domain/build/reports/detekt/detekt.sarif') != '' + uses: github/codeql-action/upload-sarif@v4.34.1 + with: + sarif_file: domain/build/reports/detekt/detekt.sarif + category: detekt-domain + + - name: Upload foundation artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: quality-foundation-reports + if-no-files-found: ignore + path: | + **/build/reports/detekt/** + **/build/reports/ktlint/** + **/build/reports/lint-results-*.html + **/build/reports/lint-results-*.xml + + build-quality-x86: + name: Build Quality (x86_64) + needs: quality-foundation + runs-on: ubuntu-24.04 + timeout-minutes: 30 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Debug build and unit tests + shell: bash + run: bash .github/scripts/quality/run_debug_build_and_unit_tests.sh + + - name: Upload quality artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: quality-build-reports-x86_64 + if-no-files-found: ignore + path: | + **/build/test-results/** + **/build/reports/tests/** + **/build/outputs/unit_test_code_coverage/** + + - name: Upload debug APK artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: debug-apks-x86_64 + if-no-files-found: error + path: | + app/build/outputs/apk/debug/app-debug.apk + app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk + + build-quality-arm64: + name: Build Quality (arm64) + needs: quality-foundation + runs-on: macos-15 + timeout-minutes: 35 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Debug build and unit tests + shell: bash + run: bash .github/scripts/quality/run_debug_build_and_unit_tests.sh + + - name: Upload quality artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: quality-build-reports-arm64 + if-no-files-found: ignore + path: | + **/build/test-results/** + **/build/reports/tests/** + **/build/outputs/unit_test_code_coverage/** + + - name: Upload debug APK artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: debug-apks-arm64 + if-no-files-found: error + path: | + app/build/outputs/apk/debug/app-debug.apk + app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk + + build-quality-windows: + name: Build Quality (windows-x86_64) + needs: quality-foundation + runs-on: windows-2025 + timeout-minutes: 35 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up Java + uses: actions/setup-java@v5.2.0 + with: + distribution: temurin + java-version: ${{ env.JAVA_VERSION }} + cache: gradle + + - name: Set up Android SDK + uses: android-actions/setup-android@v3.2.2 + with: + packages: platform-tools + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v5.0.2 + + - name: Install Android SDK packages + shell: pwsh + env: + ANDROID_API_LEVEL: ${{ env.ANDROID_API_LEVEL }} + ANDROID_BUILD_TOOLS: ${{ env.ANDROID_BUILD_TOOLS }} + INSTALL_SYSTEM_IMAGE: "false" + ANDROID_SYSTEM_IMAGE: "" + run: ./.github/scripts/setup/install_android_sdk_packages_windows.ps1 + + - name: Debug build and unit tests + shell: pwsh + run: ./.github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1 + + - name: Upload quality artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: quality-build-reports-windows-x86_64 + if-no-files-found: ignore + path: | + **/build/test-results/** + **/build/reports/tests/** + **/build/outputs/unit_test_code_coverage/** + + - name: Upload debug APK artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: debug-apks-windows-x86_64 + if-no-files-found: error + path: | + app/build/outputs/apk/debug/app-debug.apk + app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk + + coverage: + name: Coverage + needs: quality-foundation + runs-on: ubuntu-24.04 + timeout-minutes: 20 + permissions: + contents: read + pull-requests: write + checks: write + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Coverage reports and gate + shell: bash + run: bash .github/scripts/quality/run_coverage.sh + + - name: Upload coverage artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: quality-coverage-reports + if-no-files-found: ignore + path: | + **/build/reports/kover/** + + - name: Publish coverage summary + if: always() + shell: bash + run: bash .github/scripts/quality/write_coverage_summary.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..522afbe --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,73 @@ +name: Release + +on: + workflow_call: + +env: + ANDROID_API_LEVEL: "37.0" + ANDROID_BUILD_TOOLS: "37.0.0" + JAVA_VERSION: "21" + +jobs: + release-assemble: + name: Release Assemble + runs-on: ubuntu-24.04 + timeout-minutes: 25 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Assemble release variants + shell: bash + run: bash .github/scripts/release/assemble_release.sh + + - name: Upload release build artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: release-build-reports + if-no-files-found: ignore + path: | + **/build/outputs/apk/release/** + **/build/outputs/bundle/release/** + + release-lint: + name: Release Lint + needs: release-assemble + runs-on: ubuntu-24.04 + timeout-minutes: 25 + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Set up toolchain + uses: ./.github/actions/setup-android-gradle + with: + java-version: ${{ env.JAVA_VERSION }} + android-api-level: ${{ env.ANDROID_API_LEVEL }} + android-build-tools: ${{ env.ANDROID_BUILD_TOOLS }} + + - name: Lint release variants + shell: bash + run: bash .github/scripts/release/lint_release.sh + + - name: Upload release artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: release-lint-reports + if-no-files-found: ignore + path: | + **/build/reports/lint-results-*.html + **/build/reports/lint-results-*.xml diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..d82f5e4 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,41 @@ +name: Security + +on: + workflow_call: + +env: + ANDROID_API_LEVEL: "37.0" + ANDROID_BUILD_TOOLS: "37.0.0" + JAVA_VERSION: "21" + +jobs: + secrets: + name: Secrets + runs-on: ubuntu-24.04 + permissions: + contents: read + security-events: write + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + with: + fetch-depth: 0 + + - name: Run gitleaks + shell: bash + run: bash .github/scripts/security/run_gitleaks.sh + + - name: Upload gitleaks SARIF + if: always() && hashFiles('build/reports/gitleaks/gitleaks.sarif') != '' + uses: github/codeql-action/upload-sarif@v4.34.1 + with: + sarif_file: build/reports/gitleaks/gitleaks.sarif + category: gitleaks + + - name: Upload secrets artifacts + if: always() + uses: actions/upload-artifact@v7.0.0 + with: + name: secret-reports + if-no-files-found: ignore + path: build/reports/gitleaks/** diff --git a/.github/workflows/supply-chain.yml b/.github/workflows/supply-chain.yml new file mode 100644 index 0000000..f591476 --- /dev/null +++ b/.github/workflows/supply-chain.yml @@ -0,0 +1,18 @@ +name: Supply Chain + +on: + workflow_call: + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-24.04 + permissions: + contents: read + pull-requests: read + steps: + - name: Checkout + uses: actions/checkout@v6.0.2 + + - name: Review dependency changes + uses: actions/dependency-review-action@v4.9.0 diff --git a/.gitignore b/.gitignore index aa724b7..5c915a5 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ .externalNativeBuild .cxx local.properties +.idea/ diff --git a/README.md b/README.md index aad6479..e7430a3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # OpenVINO Notes -OpenVINO notes is an AI-powered notes app for Android. +OpenVINO notes is an AI-powered notes app for Android. The project is written in **Kotlin** and uses **OpenVINO** to run AI features directly on Android devices. @@ -14,7 +14,8 @@ Build a lightweight Android notes application with on-device AI for fast, privat ### Prerequisites * Android Studio (Ladybug+) * JDK 17 -* Android SDK 34 +* Android SDK 37 +* A connected Android device or a running emulator for install tasks ### Terminal Instructions @@ -24,9 +25,11 @@ git clone https://github.com/IntFxZen/openvino-notes.git 2. Build the project: ./gradlew assembleDebug -3. Install on device: +3. Start an emulator or connect a device, then install the debug build: ./gradlew installDebug +For a validated terminal-based emulator flow on, see [`docs/developer/ci-local.md`](./docs/developer/ci-local.md). + ## 🏗 Architecture & Tech Stack The project follows **Clean Architecture** principles with a multi-module setup: @@ -38,4 +41,13 @@ The project follows **Clean Architecture** principles with a multi-module setup: **Core Technologies:** * Kotlin * Android -* OpenVINO \ No newline at end of file +* OpenVINO + +## 📚 Documentation + +Project documentation now lives in [`docs/`](./docs/README.md): + +* [`docs/README.md`](./docs/README.md) - documentation index +* [`docs/developer/README.md`](./docs/developer/README.md) - contributor entry point +* [`docs/developer/project.md`](./docs/developer/project.md) - project overview +* [`docs/developer/ci-local.md`](./docs/developer/ci-local.md) - how to reproduce CI checks locally on Linux, macOS, and Windows diff --git a/ai/build.gradle.kts b/ai/build.gradle.kts index 390d6e5..2218887 100644 --- a/ai/build.gradle.kts +++ b/ai/build.gradle.kts @@ -1,12 +1,13 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) } android { namespace = "com.itlab.ai" compileSdk { - version = release(36) + version = release(37) } defaultConfig { @@ -29,8 +30,11 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) } } diff --git a/ai/gradle.lockfile b/ai/gradle.lockfile index da19f05..3a91a64 100644 --- a/ai/gradle.lockfile +++ b/ai/gradle.lockfile @@ -1,84 +1,201 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -androidx.activity:activity:1.8.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat-resources:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-jvm:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-ktx:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.dynamicanimation:dynamicanimation:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2-views-helper:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.3.6=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.6.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.profileinstaller:profileinstaller:1.3.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.2.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager2:viewpager2:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.android.material:material:1.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-stdlib:2.0.21=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kover-jvm-agent:0.9.1=koverJvmAgent -org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -empty=androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath +androidx.activity:activity:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-experimental:1.4.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.8.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.8.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.arch.core:core-runtime:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-jvm:1.4.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.collection:collection:1.4.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.constraintlayout:constraintlayout-core:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.constraintlayout:constraintlayout-solver:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.fragment:fragment:1.3.6=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.5.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-android:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.graphics:graphics-shapes:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.0=releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.ext:junit:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.services:storage:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:core:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath +androidx.tracing:tracing:1.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.2.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager2:viewpager2:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +ch.qos.logback:logback-classic:1.3.14=ktlint +ch.qos.logback:logback-core:1.3.14=ktlint +com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint +com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.material:material:1.10.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.android.material:material:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.15.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +com.google.guava:listenablefuture:1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-core:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-format:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-html:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-json:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain-summary:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-sarif:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-ruleset-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-cli:1.5.0=ktlint +com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint +com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations-jvm:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations-jvm:0.18.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations:0.18.0=ktlint,ktlintRuleset +io.github.davidburstrom.contester:contester-breakpoint:0.2.0=detekt +io.github.detekt.sarif4k:sarif4k-jvm:0.6.0=detekt,ktlint,ktlintReporter +io.github.detekt.sarif4k:sarif4k:0.6.0=detekt,ktlint,ktlintReporter +io.github.oshai:kotlin-logging-jvm:7.0.3=ktlint,ktlintReporter,ktlintRuleset +io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintReporter +io.gitlab.arturbosch.detekt:detekt-api:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-cli:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-core:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-metrics:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-parser:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-psi-utils:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-html:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-md:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-sarif:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-txt:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-xml:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-complexity:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-coroutines:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-documentation:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-empty:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-errorprone:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-exceptions:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-naming:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-performance:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset +org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +org.jcommander:jcommander:1.85=detekt +org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-bom:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-runner:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-reflect:2.0.21=detekt +org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=detekt +org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.1.0=ktlint,ktlintReporter,ktlintRuleset +org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.1=detekt +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kover-jvm-agent:0.9.7=koverJvmAgent,koverJvmReporter +org.jetbrains:annotations:13.0=detekt,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintReporter,ktlintRuleset +org.jetbrains:annotations:23.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jspecify:jspecify:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.slf4j:slf4j-api:2.0.7=ktlint +org.snakeyaml:snakeyaml-engine:2.7=detekt +empty=androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,detektPlugins,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,koverExternalArtifacts,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7702d1b..1bbae64 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,19 +1,20 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.application) - alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) } android { namespace = "com.itlab.notes" compileSdk { - version = release(36) + version = release(37) } defaultConfig { applicationId = "com.itlab.notes" minSdk = 33 - targetSdk = 36 + targetSdk = 37 versionCode = 1 versionName = "1.0" @@ -33,25 +34,37 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" - } buildFeatures { compose = true } testOptions { managedDevices { localDevices { - create("pixel7api34") { + create("pixel7api34X86") { device = "Pixel 7" apiLevel = 34 systemImageSource = "aosp-atd" + require64Bit = true + testedAbi = "x86_64" + } + create("pixel7api34Arm64") { + device = "Pixel 7" + apiLevel = 34 + systemImageSource = "aosp-atd" + require64Bit = true + testedAbi = "arm64-v8a" } } } } } +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } +} + dependencies { implementation(project(":domain")) implementation(project(":data")) @@ -71,4 +84,6 @@ dependencies { androidTestImplementation(libs.androidx.compose.ui.test.junit4) debugImplementation(libs.androidx.compose.ui.tooling) debugImplementation(libs.androidx.compose.ui.test.manifest) + implementation(libs.androidx.compose.material.icons.core) + implementation(libs.androidx.compose.material.icons.extended) } diff --git a/app/gradle.lockfile b/app/gradle.lockfile index e6561df..86a8e11 100644 --- a/app/gradle.lockfile +++ b/app/gradle.lockfile @@ -1,164 +1,308 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -androidx.activity:activity-compose:1.12.4=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.activity:activity-ktx:1.12.4=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.activity:activity:1.12.4=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-jvm:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat-resources:1.6.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.6.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.autofill:autofill:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-jvm:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-ktx:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-android:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.animation:animation-core-android:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-core-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.animation:animation-core:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-core:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.animation:animation:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-android:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout-android:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.foundation:foundation:1.7.0=releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.material3:material3-android:1.3.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material3:material3:1.3.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-android:1.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath -androidx.compose.material:material-icons-core-android:1.7.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-icons-core:1.7.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-ripple-android:1.7.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-ripple:1.7.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material:1.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-annotation-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-annotation:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-saveable-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-saveable:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-geometry-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-geometry:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-graphics-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-graphics:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-test-manifest:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-text-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-text:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-data-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-data:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-preview-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-preview:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-unit-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-unit:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-util-android:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-util:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui:1.9.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose:compose-bom:2024.09.00=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:2.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:2.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-ktx:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview-poolingcontainer:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.dynamicanimation:dynamicanimation:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2-views-helper:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.3.6=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.graphics:graphics-path:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-java8:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-compose-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-compose:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-ktx-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-ktx:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-android:1.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-compose-android:1.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-compose:1.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent:1.0.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.profileinstaller:profileinstaller:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-compose-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-compose:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-ktx:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager2:viewpager2:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.android.material:material:1.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.activity:activity-compose:1.12.4=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.activity:activity-compose:1.13.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.activity:activity-ktx:1.12.4=releaseUnitTestRuntimeClasspath +androidx.activity:activity-ktx:1.13.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.activity:activity:1.12.4=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.activity:activity:1.13.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.6.1=releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.7.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat:1.6.1=releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat:1.7.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.autofill:autofill:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-jvm:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-ktx:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.animation:animation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.animation:animation-core-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation-core-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.animation:animation-core:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation-core:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.animation:animation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.foundation:foundation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.foundation:foundation-layout-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-layout-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.foundation:foundation-layout:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-layout:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.foundation:foundation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material3:material3-android:1.3.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material3:material3-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material3:material3:1.3.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material3:material3:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-android:1.10.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath +androidx.compose.material:material-icons-core-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material:material-icons-core-android:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-core-desktop:1.7.8=releaseLintChecksClasspath +androidx.compose.material:material-icons-core:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material:material-icons-core:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-extended-android:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-extended-desktop:1.7.8=releaseLintChecksClasspath +androidx.compose.material:material-icons-extended:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-ripple-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-ripple-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material:material-ripple:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-ripple:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.material:material:1.10.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-annotation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-annotation-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-annotation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-annotation:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-retain-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-retain:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-saveable-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-saveable-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-saveable:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-saveable:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.runtime:runtime:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-geometry-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-geometry-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-geometry:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-geometry:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-graphics-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-graphics-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-graphics:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-graphics:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-test-manifest:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-text-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-text-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-text:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-text:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-data-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-data:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-preview-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-tooling-preview-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-preview:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-tooling-preview:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-unit-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-unit-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-unit:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-unit:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-util-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-util-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui-util:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-util:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.ui:ui:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose:compose-bom:2024.09.00=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose:compose-bom:2026.03.00=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout-core:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.constraintlayout:constraintlayout-solver:2.0.1=releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.0.1=releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.18.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.18.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview-poolingcontainer:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.3.6=releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.5.4=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-path:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.graphics:graphics-shapes-android:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-desktop:1.0.1=releaseLintChecksClasspath +androidx.graphics:graphics-shapes:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common-java8:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-compose-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-compose:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-ktx-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-ktx:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestRuntimeClasspath +androidx.navigationevent:navigationevent-android:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent-android:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.navigationevent:navigationevent-compose-android:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent-compose-android:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.navigationevent:navigationevent-compose:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent-compose:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.navigationevent:navigationevent:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.2.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.room:room-common-jvm:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-common:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-ktx:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-runtime-android:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-runtime:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.savedstate:savedstate-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-compose-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-compose:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-ktx:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.sqlite:sqlite-android:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework-android:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.2.0=releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager2:viewpager2:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.window:window-core-android:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.window:window-core:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.window:window:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +ch.qos.logback:logback-classic:1.3.14=ktlint +ch.qos.logback:logback-core:1.3.14=ktlint +com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint +com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.material:material:1.10.0=releaseUnitTestRuntimeClasspath +com.google.android.material:material:1.13.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.jakewharton.timber:timber:5.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-core:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-format:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-html:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-json:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain-summary:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-sarif:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-ruleset-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-cli:1.5.0=ktlint +com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint +com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations-jvm:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations-jvm:0.18.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations:0.18.0=ktlint,ktlintRuleset +io.github.davidburstrom.contester:contester-breakpoint:0.2.0=detekt +io.github.detekt.sarif4k:sarif4k-jvm:0.6.0=detekt,ktlint,ktlintReporter +io.github.detekt.sarif4k:sarif4k:0.6.0=detekt,ktlint,ktlintReporter +io.github.oshai:kotlin-logging-jvm:7.0.3=ktlint,ktlintReporter,ktlintRuleset +io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintReporter +io.gitlab.arturbosch.detekt:detekt-api:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-cli:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-core:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-metrics:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-parser:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-psi-utils:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-html:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-md:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-sarif:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-txt:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-xml:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-complexity:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-coroutines:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-documentation:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-empty:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-errorprone:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-exceptions:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-naming:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-performance:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.0.21=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest -org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-stdlib:2.0.21=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kover-jvm-agent:0.9.1=koverJvmAgent -org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -empty=androidApis,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,lintChecks,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath +org.jcommander:jcommander:1.85=detekt +org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-runner:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.0.21=kotlinCompilerPluginClasspathReleaseUnitTest +org.jetbrains.kotlin:kotlin-compose-compiler-plugin-embeddable:2.3.20=kotlin-extension,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease +org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-reflect:2.0.21=detekt +org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=detekt,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.1.0=ktlint,ktlintReporter,ktlintRuleset +org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.1=detekt +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kover-jvm-agent:0.9.7=koverJvmAgent,koverJvmReporter +org.jetbrains:annotations:13.0=detekt,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintReporter,ktlintRuleset +org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.slf4j:slf4j-api:2.0.7=ktlint +org.snakeyaml:snakeyaml-engine:2.7=detekt +empty=androidApis,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,detektPlugins,kotlinCompilerPluginClasspath,koverExternalArtifacts,lintChecks,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c8da9d2..a72e9be 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + - - + \ No newline at end of file diff --git a/app/src/main/java/com/itlab/notes/MainActivity.kt b/app/src/main/java/com/itlab/notes/MainActivity.kt index e920839..97d784a 100644 --- a/app/src/main/java/com/itlab/notes/MainActivity.kt +++ b/app/src/main/java/com/itlab/notes/MainActivity.kt @@ -4,13 +4,7 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview +import com.itlab.notes.ui.notesApp import com.itlab.notes.ui.theme.notesTheme class MainActivity : ComponentActivity() { @@ -19,32 +13,8 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { notesTheme { - Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> - greeting( - name = "Android", - modifier = Modifier.padding(innerPadding), - ) - } + notesApp() } } } } - -@Composable -fun greeting( - name: String, - modifier: Modifier = Modifier, -) { - Text( - text = "Hello $name!", - modifier = modifier, - ) -} - -@Preview(showBackground = true) -@Composable -fun greetingPreview() { - notesTheme { - greeting("Android") - } -} diff --git a/app/src/main/java/com/itlab/notes/ui/NotesApp.kt b/app/src/main/java/com/itlab/notes/ui/NotesApp.kt new file mode 100644 index 0000000..4a9e4c3 --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/NotesApp.kt @@ -0,0 +1,48 @@ +package com.itlab.notes.ui + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import com.itlab.notes.ui.editor.editorScreen +import com.itlab.notes.ui.notes.DirectoryItemUi +import com.itlab.notes.ui.notes.NoteItemUi +import com.itlab.notes.ui.notes.directoriesScreen +import com.itlab.notes.ui.notes.notesListScreen + +@Composable +fun notesApp() { + val viewModel = remember { NotesViewModel() } + val state = viewModel.uiState + + when (val screen = state.screen) { + NotesUiScreen.Directories -> { + directoriesScreen( + directories = state.directories, + onDirectoryClick = { directory -> + viewModel.onEvent(NotesUiEvent.OpenDirectory(directory)) + }, + ) + } + + is NotesUiScreen.DirectoryNotes -> { + val directory: DirectoryItemUi = screen.directory + notesListScreen( + directoryName = directory.name, + notes = state.notes, + onBack = { viewModel.onEvent(NotesUiEvent.BackToDirectories) }, + onAddNoteClick = { viewModel.onEvent(NotesUiEvent.CreateNote) }, + onNoteClick = { note: NoteItemUi -> + viewModel.onEvent(NotesUiEvent.OpenNote(note)) + }, + ) + } + + is NotesUiScreen.NoteEditor -> { + editorScreen( + directoryName = screen.directory.name, + note = screen.note, + onBack = { viewModel.onEvent(NotesUiEvent.BackToDirectoryNotes) }, + onSave = { updated -> viewModel.onEvent(NotesUiEvent.SaveNote(updated)) }, + ) + } + } +} diff --git a/app/src/main/java/com/itlab/notes/ui/NotesUiContract.kt b/app/src/main/java/com/itlab/notes/ui/NotesUiContract.kt new file mode 100644 index 0000000..a83b2e3 --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/NotesUiContract.kt @@ -0,0 +1,53 @@ +package com.itlab.notes.ui + +import com.itlab.notes.ui.notes.DirectoryItemUi +import com.itlab.notes.ui.notes.NoteItemUi + +/** + * UI contract for the Notes feature. + * Keeps state & events in one place so screens stay "dumb" (render-only). + */ +sealed interface NotesUiScreen { + data object Directories : NotesUiScreen + + data class DirectoryNotes( + val directory: DirectoryItemUi, + ) : NotesUiScreen + + data class NoteEditor( + val directory: DirectoryItemUi, + val note: NoteItemUi, + ) : NotesUiScreen +} + +data class NotesUiState( + val screen: NotesUiScreen = NotesUiScreen.Directories, + val directories: List = emptyList(), + val notes: List = emptyList(), +) + +sealed interface NotesUiEvent { + data class OpenDirectory( + val directory: DirectoryItemUi, + ) : NotesUiEvent + + data object BackToDirectories : NotesUiEvent + + data class OpenNote( + val note: NoteItemUi, + ) : NotesUiEvent + + data object CreateNote : NotesUiEvent + + data object BackToDirectoryNotes : NotesUiEvent + + data class SaveNote( + val note: NoteItemUi, + ) : NotesUiEvent +} + +interface NotesViewModelContract { + val uiState: NotesUiState + + fun onEvent(event: NotesUiEvent) +} diff --git a/app/src/main/java/com/itlab/notes/ui/NotesViewModel.kt b/app/src/main/java/com/itlab/notes/ui/NotesViewModel.kt new file mode 100644 index 0000000..39d34be --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/NotesViewModel.kt @@ -0,0 +1,162 @@ +package com.itlab.notes.ui + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import com.itlab.notes.ui.notes.DirectoryItemUi +import com.itlab.notes.ui.notes.NoteItemUi +import java.util.UUID + +class NotesViewModel : NotesViewModelContract { + override var uiState: NotesUiState by mutableStateOf( + NotesUiState( + screen = NotesUiScreen.Directories, + directories = previewDirectoriesFallback(), + ), + ) + private set + + override fun onEvent(event: NotesUiEvent) { + when (event) { + is NotesUiEvent.OpenDirectory -> openDirectory(event.directory) + NotesUiEvent.BackToDirectories -> backToDirectories() + is NotesUiEvent.OpenNote -> openNote(event.note) + NotesUiEvent.CreateNote -> createNote() + NotesUiEvent.BackToDirectoryNotes -> backToDirectoryNotes() + is NotesUiEvent.SaveNote -> saveNote(event.note) + } + } + + private fun openDirectory(directory: DirectoryItemUi) { + uiState = + uiState.copy( + screen = NotesUiScreen.DirectoryNotes(directory = directory), + notes = notesFallbackForDirectory(directory), + ) + } + + private fun backToDirectories() { + uiState = + uiState.copy( + screen = NotesUiScreen.Directories, + notes = emptyList(), + ) + } + + private fun openNote(note: NoteItemUi) { + val dir = (uiState.screen as? NotesUiScreen.DirectoryNotes)?.directory + if (dir != null) { + uiState = + uiState.copy( + screen = + NotesUiScreen.NoteEditor( + directory = dir, + note = note, + ), + ) + } + } + + private fun createNote() { + val dir = (uiState.screen as? NotesUiScreen.DirectoryNotes)?.directory + if (dir != null) { + val newNote = + NoteItemUi( + id = UUID.randomUUID().toString(), + title = "", + content = "", + ) + uiState = + uiState.copy( + screen = + NotesUiScreen.NoteEditor( + directory = dir, + note = newNote, + ), + ) + } + } + + private fun backToDirectoryNotes() { + val editor = uiState.screen as? NotesUiScreen.NoteEditor + if (editor != null) { + uiState = + uiState.copy( + screen = NotesUiScreen.DirectoryNotes(directory = editor.directory), + ) + } + } + + private fun saveNote(note: NoteItemUi) { + val editor = uiState.screen as? NotesUiScreen.NoteEditor + if (editor != null) { + val updatedNotes = uiState.notes.toMutableList() + val index = updatedNotes.indexOfFirst { it.id == note.id } + if (index >= 0) { + updatedNotes[index] = note + } else { + updatedNotes.add(note) + } + + val updatedDirectory = editor.directory.copy(noteCount = updatedNotes.size) + uiState = + uiState.copy( + screen = NotesUiScreen.DirectoryNotes(directory = updatedDirectory), + notes = updatedNotes, + ) + } + } + + private fun notesFallbackForDirectory(directory: DirectoryItemUi): List = + when (directory.name) { + "My Study" -> + listOf( + NoteItemUi( + id = "my-study-1", + title = "Lecture notes", + content = "Topic: coroutines\n- suspend\n- scope\n- dispatcher", + ), + NoteItemUi( + id = "my-study-2", + title = "Homework", + content = "Due Friday.\nChecklist:\n1) ...\n2) ...", + ), + ) + + "How to Cook" -> + listOf( + NoteItemUi( + id = "cook-1", + title = "Cherry pie", + content = "Ingredients:\n- Flour 300g\n- Cherries 200g\n- Sugar 120g", + ), + NoteItemUi( + id = "cook-2", + title = "Pasta", + content = "Sauce: tomatoes + garlic + basil.\nTime: 20 minutes.", + ), + ) + + else -> + listOf( + NoteItemUi( + id = "other-1", + title = "First note", + content = "Temporary placeholder while notes load from the data layer.", + ), + NoteItemUi( + id = "other-2", + title = "Second note", + content = "Connect the data layer and pass the list into UI.", + ), + ) + } + + private fun previewDirectoriesFallback(): List = + listOf( + DirectoryItemUi(name = "All Notes", noteCount = 0), + DirectoryItemUi(name = "My Study", noteCount = 0), + DirectoryItemUi(name = "How to Cook", noteCount = 0), + DirectoryItemUi(name = "My poems", noteCount = 0), + ) +} diff --git a/app/src/main/java/com/itlab/notes/ui/editor/EditorScreen.kt b/app/src/main/java/com/itlab/notes/ui/editor/EditorScreen.kt index 681235c..aa826b2 100644 --- a/app/src/main/java/com/itlab/notes/ui/editor/EditorScreen.kt +++ b/app/src/main/java/com/itlab/notes/ui/editor/EditorScreen.kt @@ -1,10 +1,195 @@ package com.itlab.notes.ui.editor +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Check +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.itlab.notes.ui.notes.NoteItemUi +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun editorScreen(modifier: Modifier = Modifier) { - Text(text = "Editor", modifier = modifier) +fun editorScreen( + directoryName: String, + note: NoteItemUi, + onBack: () -> Unit, + onSave: (NoteItemUi) -> Unit, +) { + val colors = MaterialTheme.colorScheme + val editorVm = remember(note.id) { EditorViewModel(initialNote = note) } + + Scaffold( + containerColor = colors.background, + topBar = { + editorTopBar( + directoryName = directoryName, + title = editorVm.title, + onBack = onBack, + ) + }, + floatingActionButton = { + editorFab( + onClick = { onSave(editorVm.buildUpdatedNote()) }, + ) + }, + ) { paddingValues -> + editorContent( + title = editorVm.title, + content = editorVm.content, + onTitleChange = editorVm::onTitleChange, + onContentChange = editorVm::onContentChange, + modifier = Modifier.padding(paddingValues), + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun editorTopBar( + directoryName: String, + title: String, + onBack: () -> Unit, +) { + val colors = MaterialTheme.colorScheme + CenterAlignedTopAppBar( + title = { + Text( + text = if (title.isBlank()) directoryName else title, + color = colors.onSurface, + ) + }, + navigationIcon = { + IconButton(onClick = onBack) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = null, + tint = colors.onSurface, + ) + } + }, + colors = + TopAppBarDefaults.topAppBarColors( + containerColor = Color.Transparent, + scrolledContainerColor = Color.Unspecified, + navigationIconContentColor = Color.Unspecified, + titleContentColor = Color.Unspecified, + actionIconContentColor = Color.Unspecified, + ), + ) +} + +@Composable +private fun editorFab(onClick: () -> Unit) { + val colors = MaterialTheme.colorScheme + FloatingActionButton( + onClick = onClick, + containerColor = colors.primary, + ) { + Icon( + Icons.Default.Check, + contentDescription = null, + tint = colors.onPrimary, + ) + } +} + +@Composable +private fun editorContent( + title: String, + content: String, + onTitleChange: (String) -> Unit, + onContentChange: (String) -> Unit, + modifier: Modifier = Modifier, +) { + val colors = MaterialTheme.colorScheme + Column( + modifier = + modifier + .fillMaxSize() + .padding(horizontal = 16.dp, vertical = 12.dp), + ) { + editorTitleField( + value = title, + onValueChange = onTitleChange, + ) + + editorContentField( + value = content, + onValueChange = onContentChange, + modifier = Modifier.padding(top = 12.dp), + ) + } +} + +@Composable +private fun editorTitleField( + value: String, + onValueChange: (String) -> Unit, +) { + val colors = MaterialTheme.colorScheme + TextField( + value = value, + onValueChange = onValueChange, + placeholder = { Text("Title") }, + singleLine = true, + colors = + TextFieldDefaults.colors( + focusedTextColor = colors.onSurface, + unfocusedTextColor = colors.onSurface, + focusedPlaceholderColor = colors.onSurfaceVariant, + unfocusedPlaceholderColor = colors.onSurfaceVariant, + focusedContainerColor = colors.background, + unfocusedContainerColor = colors.background, + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + errorIndicatorColor = Color.Transparent, + ), + ) +} + +@Composable +private fun editorContentField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, +) { + val colors = MaterialTheme.colorScheme + TextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + placeholder = { Text("Input") }, + minLines = 12, + colors = + TextFieldDefaults.colors( + focusedTextColor = colors.onSurface, + unfocusedTextColor = colors.onSurface, + focusedPlaceholderColor = colors.onSurfaceVariant, + unfocusedPlaceholderColor = colors.onSurfaceVariant, + focusedContainerColor = colors.background, + unfocusedContainerColor = colors.background, + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + errorIndicatorColor = Color.Transparent, + ), + ) } diff --git a/app/src/main/java/com/itlab/notes/ui/editor/EditorViewModel.kt b/app/src/main/java/com/itlab/notes/ui/editor/EditorViewModel.kt index e28958c..4e448ff 100644 --- a/app/src/main/java/com/itlab/notes/ui/editor/EditorViewModel.kt +++ b/app/src/main/java/com/itlab/notes/ui/editor/EditorViewModel.kt @@ -1,3 +1,33 @@ package com.itlab.notes.ui.editor -class EditorViewModel +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import com.itlab.notes.ui.notes.NoteItemUi + +class EditorViewModel( + initialNote: NoteItemUi, +) { + private val noteId: String = initialNote.id + + var title: String by mutableStateOf(initialNote.title) + private set + + var content: String by mutableStateOf(initialNote.content) + private set + + fun onTitleChange(newTitle: String) { + title = newTitle + } + + fun onContentChange(newContent: String) { + content = newContent + } + + fun buildUpdatedNote(): NoteItemUi = + NoteItemUi( + id = noteId, + title = title, + content = content, + ) +} diff --git a/app/src/main/java/com/itlab/notes/ui/notes/DirectoriesScreen.kt b/app/src/main/java/com/itlab/notes/ui/notes/DirectoriesScreen.kt new file mode 100644 index 0000000..451bb57 --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/notes/DirectoriesScreen.kt @@ -0,0 +1,148 @@ +package com.itlab.notes.ui.notes + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.ChevronRight +import androidx.compose.material.icons.filled.Stars +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun directoriesScreen( + directories: List = previewDirectoriesFallback(), + onDirectoryClick: (DirectoryItemUi) -> Unit, +) { + val colors = MaterialTheme.colorScheme + + Scaffold( + containerColor = colors.background, + topBar = { + directoriesTopBar() + }, + ) { paddingValues -> + directoriesList( + directories = directories, + onDirectoryClick = onDirectoryClick, + modifier = Modifier.padding(paddingValues), + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun directoriesTopBar() { + val colors = MaterialTheme.colorScheme + CenterAlignedTopAppBar( + title = { Text("Directories", color = colors.onSurface) }, + actions = { + IconButton(onClick = {}) { + Icon( + Icons.Default.Add, + contentDescription = null, + tint = colors.onSurface, + ) + } + }, + colors = + TopAppBarDefaults.topAppBarColors( + containerColor = Color.Transparent, + scrolledContainerColor = Color.Unspecified, + navigationIconContentColor = Color.Unspecified, + titleContentColor = Color.Unspecified, + actionIconContentColor = Color.Unspecified, + ), + ) +} + +@Composable +private fun directoriesList( + directories: List, + onDirectoryClick: (DirectoryItemUi) -> Unit, + modifier: Modifier = Modifier, +) { + LazyColumn(modifier = modifier.padding(horizontal = 16.dp)) { + items(directories) { dir -> + directoryRow( + directory = dir, + onClick = { onDirectoryClick(dir) }, + ) + } + } +} + +@Composable +private fun directoryRow( + directory: DirectoryItemUi, + onClick: () -> Unit, +) { + val colors = MaterialTheme.colorScheme + Row( + modifier = + Modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + Icons.Default.Stars, + contentDescription = null, + tint = colors.primary, + modifier = Modifier.size(24.dp), + ) + Spacer(Modifier.width(16.dp)) + Text( + text = directory.name, + color = colors.onSurface, + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.weight(1f), + ) + Surface( + color = colors.surfaceVariant, + shape = CircleShape, + ) { + Text( + text = directory.noteCount.toString(), + color = colors.onSurfaceVariant, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp), + style = MaterialTheme.typography.labelSmall, + ) + } + Icon( + Icons.Default.ChevronRight, + contentDescription = null, + tint = colors.onSurfaceVariant, + ) + } +} + +private fun previewDirectoriesFallback(): List = + listOf( + DirectoryItemUi(name = "All Notes", noteCount = 0), + DirectoryItemUi(name = "My Study", noteCount = 0), + DirectoryItemUi(name = "How to Cook", noteCount = 0), + DirectoryItemUi(name = "My poems", noteCount = 0), + ) diff --git a/app/src/main/java/com/itlab/notes/ui/notes/DirectoryItemUi.kt b/app/src/main/java/com/itlab/notes/ui/notes/DirectoryItemUi.kt new file mode 100644 index 0000000..000674c --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/notes/DirectoryItemUi.kt @@ -0,0 +1,6 @@ +package com.itlab.notes.ui.notes + +data class DirectoryItemUi( + val name: String, + val noteCount: Int, +) diff --git a/app/src/main/java/com/itlab/notes/ui/notes/NoteItemUi.kt b/app/src/main/java/com/itlab/notes/ui/notes/NoteItemUi.kt new file mode 100644 index 0000000..fc9aa79 --- /dev/null +++ b/app/src/main/java/com/itlab/notes/ui/notes/NoteItemUi.kt @@ -0,0 +1,7 @@ +package com.itlab.notes.ui.notes + +data class NoteItemUi( + val id: String, + val title: String, + val content: String, +) diff --git a/app/src/main/java/com/itlab/notes/ui/notes/NotesScreen.kt b/app/src/main/java/com/itlab/notes/ui/notes/NotesScreen.kt index 72d4066..b4c4e50 100644 --- a/app/src/main/java/com/itlab/notes/ui/notes/NotesScreen.kt +++ b/app/src/main/java/com/itlab/notes/ui/notes/NotesScreen.kt @@ -1,10 +1,208 @@ package com.itlab.notes.ui.notes +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Menu +import androidx.compose.material.icons.filled.Search +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun notesScreen(modifier: Modifier = Modifier) { - Text(text = "Notes", modifier = modifier) +fun notesListScreen( + directoryName: String, + notes: List, + onBack: () -> Unit, + onAddNoteClick: () -> Unit, + onNoteClick: (NoteItemUi) -> Unit, +) { + val colors = MaterialTheme.colorScheme + + Scaffold( + containerColor = colors.background, + topBar = { + notesTopBar( + directoryName = directoryName, + onBack = onBack, + ) + }, + floatingActionButton = { + notesFab(onAddNoteClick = onAddNoteClick) + }, + ) { paddingValues -> + notesListContent( + notes = notes, + paddingValues = paddingValues, + onNoteClick = onNoteClick, + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun notesTopBar( + directoryName: String, + onBack: () -> Unit, +) { + val colors = MaterialTheme.colorScheme + CenterAlignedTopAppBar( + title = { Text(directoryName, color = colors.onSurface) }, + navigationIcon = { + IconButton(onClick = onBack) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = null, + tint = colors.onSurface, + ) + } + }, + colors = + TopAppBarDefaults.topAppBarColors( + containerColor = Color.Transparent, + scrolledContainerColor = Color.Unspecified, + navigationIconContentColor = Color.Unspecified, + titleContentColor = Color.Unspecified, + actionIconContentColor = Color.Unspecified, + ), + ) +} + +@Composable +private fun notesFab(onAddNoteClick: () -> Unit) { + val colors = MaterialTheme.colorScheme + FloatingActionButton( + onClick = onAddNoteClick, + containerColor = colors.primary, + ) { + Icon( + Icons.Default.Add, + contentDescription = null, + tint = colors.onPrimary, + ) + } +} + +@Composable +private fun notesListContent( + notes: List, + paddingValues: androidx.compose.foundation.layout.PaddingValues, + onNoteClick: (NoteItemUi) -> Unit, +) { + Column( + modifier = + Modifier + .padding(paddingValues) + .padding(horizontal = 16.dp), + ) { + searchField() + + LazyColumn( + verticalArrangement = Arrangement.spacedBy(12.dp), + modifier = Modifier.padding(top = 4.dp), + ) { + items(notes) { note -> + noteCard( + note = note, + onClick = { onNoteClick(note) }, + ) + } + } + } +} + +@Composable +private fun noteCard( + note: NoteItemUi, + onClick: () -> Unit, +) { + val colors = MaterialTheme.colorScheme + + Card( + colors = CardDefaults.cardColors(containerColor = colors.surfaceVariant), + shape = RoundedCornerShape(16.dp), + modifier = + Modifier + .fillMaxWidth() + .clickable(onClick = onClick), + ) { + Column(modifier = Modifier.padding(16.dp).fillMaxWidth()) { + Text( + text = note.title, + color = colors.onSurface, + style = MaterialTheme.typography.titleMedium, + ) + Spacer(Modifier.height(8.dp)) + Text( + text = note.content, + color = colors.onSurfaceVariant, + style = MaterialTheme.typography.bodySmall, + maxLines = 4, + ) + } + } +} + +@Composable +private fun searchField() { + val colors = MaterialTheme.colorScheme + + Surface( + color = colors.surfaceVariant.copy(alpha = 0.65f), + shape = RoundedCornerShape(24.dp), + modifier = + Modifier + .fillMaxWidth() + .padding(vertical = 16.dp), + ) { + Row( + modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + Icons.Default.Menu, + contentDescription = null, + tint = colors.onSurfaceVariant, + ) + Text( + text = "Hinted search text", + color = colors.onSurfaceVariant, + modifier = + Modifier + .padding(horizontal = 16.dp) + .weight(1f), + ) + Icon( + Icons.Default.Search, + contentDescription = null, + tint = colors.onSurfaceVariant, + ) + } + } } diff --git a/app/src/main/java/com/itlab/notes/ui/theme/Theme.kt b/app/src/main/java/com/itlab/notes/ui/theme/Theme.kt index 28547c9..dd27368 100644 --- a/app/src/main/java/com/itlab/notes/ui/theme/Theme.kt +++ b/app/src/main/java/com/itlab/notes/ui/theme/Theme.kt @@ -9,33 +9,23 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext -private val DarkColorScheme = +private val darkColorSchemeValues = darkColorScheme( primary = Purple80, secondary = PurpleGrey80, tertiary = Pink80, ) -private val LightColorScheme = +private val lightColorSchemeValues = lightColorScheme( primary = Purple40, secondary = PurpleGrey40, tertiary = Pink40, - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ ) @Composable fun notesTheme( darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ dynamicColor: Boolean = true, content: @Composable () -> Unit, ) { @@ -43,11 +33,15 @@ fun notesTheme( when { dynamicColor -> { val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + if (darkTheme) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } } - darkTheme -> DarkColorScheme - else -> LightColorScheme + darkTheme -> darkColorSchemeValues + else -> lightColorSchemeValues } MaterialTheme( diff --git a/app/src/main/java/com/itlab/notes/ui/theme/Type.kt b/app/src/main/java/com/itlab/notes/ui/theme/Type.kt index ff8d468..e16c538 100644 --- a/app/src/main/java/com/itlab/notes/ui/theme/Type.kt +++ b/app/src/main/java/com/itlab/notes/ui/theme/Type.kt @@ -6,7 +6,6 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp -// Set of Material typography styles to start with val Typography = Typography( bodyLarge = @@ -17,20 +16,4 @@ val Typography = lineHeight = 24.sp, letterSpacing = 0.5.sp, ), - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ ) diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..55344e5 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 2c00367..ba7114d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,12 +9,12 @@ import org.jlleitschuh.gradle.ktlint.KtlintExtension // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { alias(libs.plugins.android.application) apply false - alias(libs.plugins.kotlin.android) apply false alias(libs.plugins.kotlin.compose) apply false alias(libs.plugins.android.library) apply false alias(libs.plugins.ktlint) alias(libs.plugins.detekt) alias(libs.plugins.kover) + kotlin("plugin.serialization") version "2.3.20" apply false } configure { @@ -113,6 +113,7 @@ subprojects { } tasks.withType().configureEach { + jvmTarget = "21" reports { html.required.set(true) md.required.set(false) @@ -141,8 +142,8 @@ subprojects { } } -fun CommonExtension<*, *, *, *, *, *>.configureAndroidLint() { - lint { +fun CommonExtension.configureAndroidLint() { + lint.apply { abortOnError = true checkAllWarnings = true checkDependencies = true diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 2a275b9..d7aab12 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -1,13 +1,14 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) + alias(libs.plugins.ksp) + alias(libs.plugins.kotlin.serialization) } android { namespace = "com.itlab.data" - compileSdk { - version = release(36) - } + compileSdk = 37 defaultConfig { minSdk = 33 @@ -25,21 +26,37 @@ android { ) } } + compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } - kotlinOptions { - jvmTarget = "11" +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) } } dependencies { + implementation(project(":domain")) implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) - implementation(project(":domain")) + implementation(libs.room.runtime) + implementation(libs.room.ktx) + ksp(libs.room.compiler) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) + implementation(libs.timber) + testImplementation(libs.junit) testImplementation(libs.junit) + testImplementation(libs.kotlinx.coroutines.test) + testImplementation(libs.mockk) + testImplementation(libs.robolectric) + testImplementation(libs.androidx.test.core) + testImplementation(libs.androidx.test.ext.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) } diff --git a/data/gradle.lockfile b/data/gradle.lockfile index da19f05..324353b 100644 --- a/data/gradle.lockfile +++ b/data/gradle.lockfile @@ -1,84 +1,304 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -androidx.activity:activity:1.8.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat-resources:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-jvm:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-ktx:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.dynamicanimation:dynamicanimation:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2-views-helper:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.3.6=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.6.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.profileinstaller:profileinstaller:1.3.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.2.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager2:viewpager2:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.android.material:material:1.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-stdlib:2.0.21=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kover-jvm-agent:0.9.1=koverJvmAgent -org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -empty=androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath +androidx.activity:activity:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-experimental:1.4.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.9.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.annotation:annotation:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.9.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat-resources:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.arch.core:core-runtime:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-jvm:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.constraintlayout:constraintlayout-core:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.constraintlayout:constraintlayout-solver:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.fragment:fragment:1.3.6=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.5.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-android:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.graphics:graphics-shapes:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.0=releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.room:room-common-jvm:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-common:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-compiler-processing:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +androidx.room:room-compiler:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +androidx.room:room-external-antlr:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +androidx.room:room-ktx:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-migration-jvm:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +androidx.room:room-migration:2.7.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +androidx.room:room-runtime-android:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-runtime:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.savedstate:savedstate:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.sqlite:sqlite-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.5.1=debugUnitTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.ext:junit:1.1.5=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.test.ext:junit:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.services:storage:1.4.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.test.services:storage:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:annotation:1.0.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.test:core:1.5.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.test:core:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:monitor:1.6.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.tracing:tracing:1.0.0=debugUnitTestCompileClasspath +androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath +androidx.tracing:tracing:1.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.2.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager2:viewpager2:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +ch.qos.logback:logback-classic:1.3.14=ktlint +ch.qos.logback:logback-core:1.3.14=ktlint +com.almworks.sqlite4java:sqlite4java:1.0.392=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint +com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.material:material:1.10.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.android.material:material:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.auto.value:auto-value-annotations:1.10.4=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.auto.value:auto-value-annotations:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.auto:auto-common:1.2.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.code.findbugs:jsr305:3.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.devtools.ksp:symbol-processing-api:2.0.10-1.0.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.devtools.ksp:symbol-processing:2.3.6=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease +com.google.errorprone:error_prone_annotation:2.19.1=debugUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.11.0=debugUnitTestCompileClasspath +com.google.errorprone:error_prone_annotations:2.15.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.26.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +com.google.guava:failureaccess:1.0.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.guava:failureaccess:1.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.guava:guava:31.1-jre=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.guava:guava:33.2.1-jre=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.guava:listenablefuture:1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.j2objc:j2objc-annotations:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.ibm.icu:icu4j:74.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.intellij:annotations:12.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.jakewharton.timber:timber:5.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-core:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-format:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-html:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-json:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain-summary:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-sarif:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-ruleset-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-cli:1.5.0=ktlint +com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint +com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +com.squareup:javapoet:1.13.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.squareup:kotlinpoet-javapoet:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.squareup:kotlinpoet-jvm:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.squareup:kotlinpoet:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +commons-codec:commons-codec:1.15=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +dev.drewhamilton.poko:poko-annotations-jvm:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations-jvm:0.18.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations:0.18.0=ktlint,ktlintRuleset +io.github.davidburstrom.contester:contester-breakpoint:0.2.0=detekt +io.github.detekt.sarif4k:sarif4k-jvm:0.6.0=detekt,ktlint,ktlintReporter +io.github.detekt.sarif4k:sarif4k:0.6.0=detekt,ktlint,ktlintReporter +io.github.oshai:kotlin-logging-jvm:7.0.3=ktlint,ktlintReporter,ktlintRuleset +io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintReporter +io.gitlab.arturbosch.detekt:detekt-api:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-cli:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-core:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-metrics:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-parser:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-psi-utils:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-html:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-md:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-sarif:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-txt:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-xml:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-complexity:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-coroutines:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-documentation:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-empty:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-errorprone:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-exceptions:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-naming:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-performance:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt +io.mockk:mockk-agent-api-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-agent-api:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-agent-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-agent:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-core-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-core:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-dsl-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-dsl:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.mockk:mockk:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +javax.annotation:javax.annotation-api:1.3.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +net.bytebuddy:byte-buddy-agent:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +net.bytebuddy:byte-buddy:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.bouncycastle:bcprov-jdk18on:1.77=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.checkerframework:checker-qual:3.12.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.checkerframework:checker-qual:3.42.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.conscrypt:conscrypt-openjdk-uber:2.5.2=debugUnitTestRuntimeClasspath +org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset +org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +org.jcommander:jcommander:1.85=detekt +org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-bom:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-runner:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-reflect:1.9.10=debugUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-reflect:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-reflect:2.0.21=detekt +org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:2.3.20=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease +org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=detekt +org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-common:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.1.0=ktlint,ktlintReporter,ktlintRuleset +org.jetbrains.kotlin:kotlin-stdlib:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.1=detekt +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kover-jvm-agent:0.9.7=koverJvmAgent +org.jetbrains:annotations:13.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,detekt,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,ktlint,ktlintReporter,ktlintRuleset +org.jetbrains:annotations:23.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jspecify:jspecify:1.0.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.junit.jupiter:junit-jupiter-api:5.8.2=debugUnitTestRuntimeClasspath +org.junit.jupiter:junit-jupiter-engine:5.8.2=debugUnitTestRuntimeClasspath +org.junit.jupiter:junit-jupiter-params:5.8.2=debugUnitTestRuntimeClasspath +org.junit.jupiter:junit-jupiter:5.8.2=debugUnitTestRuntimeClasspath +org.junit.platform:junit-platform-commons:1.8.2=debugUnitTestRuntimeClasspath +org.junit.platform:junit-platform-engine:1.8.2=debugUnitTestRuntimeClasspath +org.junit:junit-bom:5.8.2=debugUnitTestRuntimeClasspath +org.objenesis:objenesis:3.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.opentest4j:opentest4j:1.2.0=debugUnitTestRuntimeClasspath +org.ow2.asm:asm-analysis:9.7=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.ow2.asm:asm-commons:9.7=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.ow2.asm:asm-tree:9.7=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.ow2.asm:asm-util:9.7=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.ow2.asm:asm:9.7=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:annotations:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:junit:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:nativeruntime-dist-compat:1.0.9=debugUnitTestRuntimeClasspath +org.robolectric:nativeruntime:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:pluginapi:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:plugins-maven-dependency-resolver:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:resources:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:robolectric:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:sandbox:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:shadowapi:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:shadows-framework:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:shadows-versioning:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:utils-reflector:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.robolectric:utils:4.12.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.slf4j:slf4j-api:2.0.7=ktlint +org.snakeyaml:snakeyaml-engine:2.7=detekt +org.xerial:sqlite-jdbc:3.41.2.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +empty=_agp_internal_debugUnitTest_kspClasspath,androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,detektPlugins,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathReleaseUnitTest,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath diff --git a/data/src/androidTest/java/com/itlab/data/FolderDaoTest.kt b/data/src/androidTest/java/com/itlab/data/FolderDaoTest.kt new file mode 100644 index 0000000..e5e2871 --- /dev/null +++ b/data/src/androidTest/java/com/itlab/data/FolderDaoTest.kt @@ -0,0 +1,72 @@ +package com.itlab.data + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.itlab.data.dao.FolderDao +import com.itlab.data.db.AppDatabase +import com.itlab.data.entity.FolderEntity +import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Clock +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class FolderDaoTest { + private lateinit var db: AppDatabase + private lateinit var dao: FolderDao + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build() + dao = db.folderDao() + } + + @After + fun closeDb() { + db.close() + } + + @Test + fun writeFolderAndReadInList() = + runTest { + val folder = + FolderEntity( + id = "folder_1", + name = "Work", + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + metadata = mapOf("tag" to "urgent", "icon_id" to "123"), + ) + + dao.insert(folder) + val result = dao.getFolderById("folder_1") + + assertEquals(folder.name, result?.name) + assertEquals("urgent", result?.metadata?.get("tag")) + } + + @Test + fun writeFolderWithEmptyMetadata() = + runTest { + val folder = + FolderEntity( + id = "folder_empty", + name = "Empty Meta", + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + metadata = emptyMap(), + ) + + dao.insert(folder) + val result = dao.getFolderById("folder_empty") + + assertTrue(result?.metadata?.isEmpty() == true) + } +} diff --git a/data/src/androidTest/java/com/itlab/data/NoteAndMediaCascadeTest.kt b/data/src/androidTest/java/com/itlab/data/NoteAndMediaCascadeTest.kt new file mode 100644 index 0000000..f44987f --- /dev/null +++ b/data/src/androidTest/java/com/itlab/data/NoteAndMediaCascadeTest.kt @@ -0,0 +1,70 @@ +package com.itlab.data + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.itlab.data.dao.MediaDao +import com.itlab.data.dao.NoteDao +import com.itlab.data.db.AppDatabase +import com.itlab.data.entity.MediaEntity +import com.itlab.data.entity.NoteEntity +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class NoteAndMediaCascadeTest { + private lateinit var db: AppDatabase + private lateinit var noteDao: NoteDao + private lateinit var mediaDao: MediaDao + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + + db = + Room + .inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, + ).build() + noteDao = db.noteDao() + mediaDao = db.mediaDao() + } + + @After + fun closeDb() { + db.close() + } + + @Test + fun verifyCascadeDelete_whenNoteDeleted_mediaIsAlsoDeleted() = + runBlocking { + val note = NoteEntity(id = "note_1", title = "Test", content = "Test") + val media = + MediaEntity( + id = "media_1", + noteId = "note_1", + type = "image", + remoteUrl = "", + localPath = null, + mimeType = "image/jpeg", + ) + + noteDao.insert(note) + mediaDao.insert(media) + + val mediaBeforeDelete = mediaDao.getMediaForNote("note_1") + assertEquals(1, mediaBeforeDelete.size) + + noteDao.delete(note) + + val mediaAfterDelete = mediaDao.getMediaForNote("note_1") + assertTrue(mediaAfterDelete.isEmpty()) + } +} diff --git a/data/src/main/java/com/itlab/data/dao/FolderDao.kt b/data/src/main/java/com/itlab/data/dao/FolderDao.kt new file mode 100644 index 0000000..f9e1e9d --- /dev/null +++ b/data/src/main/java/com/itlab/data/dao/FolderDao.kt @@ -0,0 +1,37 @@ +package com.itlab.data.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Update +import com.itlab.data.entity.FolderEntity +import kotlinx.coroutines.flow.Flow + +@Dao +interface FolderDao { + @Query("SELECT * FROM folders ORDER BY name ASC") + fun getAllFolders(): Flow> + + @Query("SELECT * FROM folders WHERE id = :id") + suspend fun getFolderById(id: String): FolderEntity? + + @Query("DELETE FROM folders") + suspend fun deleteAll() + + @Query("UPDATE folders SET name = :name WHERE id = :id") + suspend fun updateName( + id: String, + name: String, + ) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insert(folder: FolderEntity) + + @Update + suspend fun update(folder: FolderEntity) + + @Delete + suspend fun delete(folder: FolderEntity) +} diff --git a/data/src/main/java/com/itlab/data/dao/MediaDao.kt b/data/src/main/java/com/itlab/data/dao/MediaDao.kt new file mode 100644 index 0000000..e0131c8 --- /dev/null +++ b/data/src/main/java/com/itlab/data/dao/MediaDao.kt @@ -0,0 +1,33 @@ +package com.itlab.data.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.itlab.data.entity.MediaEntity +import kotlinx.coroutines.flow.Flow + +@Dao +interface MediaDao { + @Query("SELECT * FROM media WHERE noteId = :noteId") + fun getMediaForNoteFlow(noteId: String): Flow> + + @Query("SELECT * FROM media WHERE noteId = :noteId") + suspend fun getMediaForNote(noteId: String): List + + @Query("DELETE FROM media WHERE noteId = :noteId") + suspend fun deleteByNoteId(noteId: String) + + @Query("DELETE FROM media") + suspend fun deleteAll() + + @Insert + suspend fun insert(media: MediaEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(mediaList: List) + + @Delete + suspend fun delete(media: MediaEntity) +} diff --git a/data/src/main/java/com/itlab/data/dao/NoteDao.kt b/data/src/main/java/com/itlab/data/dao/NoteDao.kt new file mode 100644 index 0000000..3da3c37 --- /dev/null +++ b/data/src/main/java/com/itlab/data/dao/NoteDao.kt @@ -0,0 +1,43 @@ +package com.itlab.data.dao + +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Update +import com.itlab.data.entity.NoteEntity +import kotlinx.coroutines.flow.Flow + +@Dao +interface NoteDao { + @Query("SELECT * FROM notes WHERE isDeleted = 0 ORDER BY updatedAt DESC") + fun getAllNotes(): Flow> + + @Query("SELECT * FROM notes WHERE id = :noteId") + suspend fun getNoteByld(noteId: String): NoteEntity? + + @Query("SELECT * FROM notes WHERE folderId = :folderId ORDER BY updatedAt DESC") + fun getNotesByFolder(folderId: String): Flow> + + @Query("SELECT * FROM notes WHERE isSynced = 0 AND isDeleted = 0") + suspend fun getUnsyncedNotes(): List + + @Query("SELECT * FROM notes WHERE isDeleted = 1") + suspend fun getDeletedNotes(): List + + @Query("DELETE FROM notes WHERE id = :id") + suspend fun hardDeleteById(id: String) + + @Insert + suspend fun insert(note: NoteEntity) + + @Update + suspend fun update(note: NoteEntity) + + @Delete + suspend fun delete(note: NoteEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertAll(notes: List) +} diff --git a/data/src/main/java/com/itlab/data/db/AppDatabase.kt b/data/src/main/java/com/itlab/data/db/AppDatabase.kt new file mode 100644 index 0000000..9c51bb4 --- /dev/null +++ b/data/src/main/java/com/itlab/data/db/AppDatabase.kt @@ -0,0 +1,25 @@ +package com.itlab.data.db + +import androidx.room.Database +import androidx.room.RoomDatabase +import androidx.room.TypeConverters +import com.itlab.data.dao.FolderDao +import com.itlab.data.dao.MediaDao +import com.itlab.data.dao.NoteDao +import com.itlab.data.entity.FolderEntity +import com.itlab.data.entity.MediaEntity +import com.itlab.data.entity.NoteEntity + +@Database( + entities = [NoteEntity::class, MediaEntity::class, FolderEntity::class], + version = 1, + exportSchema = false, +) +@TypeConverters(DateTimeConverters::class, MetadataConverter::class) +abstract class AppDatabase : RoomDatabase() { + abstract fun noteDao(): NoteDao + + abstract fun mediaDao(): MediaDao + + abstract fun folderDao(): FolderDao +} diff --git a/data/src/main/java/com/itlab/data/db/DateTimeConverters.kt b/data/src/main/java/com/itlab/data/db/DateTimeConverters.kt new file mode 100644 index 0000000..26be5a8 --- /dev/null +++ b/data/src/main/java/com/itlab/data/db/DateTimeConverters.kt @@ -0,0 +1,15 @@ +package com.itlab.data.db + +import androidx.room.TypeConverter +import kotlinx.datetime.Instant + +class DateTimeConverters { + @TypeConverter + fun fromTimestamp(value: Long?): Instant? = + value?.let { + Instant.fromEpochMilliseconds(it) + } + + @TypeConverter + fun dateToTimestamp(date: Instant?): Long? = date?.toEpochMilliseconds() +} diff --git a/data/src/main/java/com/itlab/data/db/MetadataConverter.kt b/data/src/main/java/com/itlab/data/db/MetadataConverter.kt new file mode 100644 index 0000000..70f5920 --- /dev/null +++ b/data/src/main/java/com/itlab/data/db/MetadataConverter.kt @@ -0,0 +1,21 @@ +package com.itlab.data.db + +import androidx.room.TypeConverter +import kotlinx.serialization.SerializationException +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import timber.log.Timber + +class MetadataConverter { + @TypeConverter + fun fromMetadata(metadata: Map): String = Json.encodeToString(metadata) + + @TypeConverter + fun toMetadata(metadataString: String): Map = + try { + Json.decodeFromString(metadataString) + } catch (e: SerializationException) { + Timber.e(e, "Failed to parse metadata") + emptyMap() + } +} diff --git a/data/src/main/java/com/itlab/data/entity/FolderEntity.kt b/data/src/main/java/com/itlab/data/entity/FolderEntity.kt new file mode 100644 index 0000000..82d4ab8 --- /dev/null +++ b/data/src/main/java/com/itlab/data/entity/FolderEntity.kt @@ -0,0 +1,16 @@ +package com.itlab.data.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.datetime.Instant + +@Entity(tableName = "folders") +data class FolderEntity( + @PrimaryKey val id: String, + val name: String, + val createdAt: Instant, + val updatedAt: Instant, + val isSynced: Boolean = false, + val isDeleted: Boolean = false, + val metadata: Map, +) diff --git a/data/src/main/java/com/itlab/data/entity/MediaEntity.kt b/data/src/main/java/com/itlab/data/entity/MediaEntity.kt new file mode 100644 index 0000000..90fe3d7 --- /dev/null +++ b/data/src/main/java/com/itlab/data/entity/MediaEntity.kt @@ -0,0 +1,30 @@ +package com.itlab.data.entity + +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.Index +import androidx.room.PrimaryKey + +@Entity( + tableName = "media", + indices = [Index(value = ["noteId"])], + foreignKeys = [ + ForeignKey( + entity = NoteEntity::class, + parentColumns = ["id"], + childColumns = ["noteId"], + onDelete = ForeignKey.CASCADE, + ), + ], +) +data class MediaEntity( + @PrimaryKey + val id: String, + val noteId: String, + val type: String, + val remoteUrl: String?, + val localPath: String?, + val mimeType: String, + val isSynced: Boolean = false, + val size: Long? = null, +) diff --git a/data/src/main/java/com/itlab/data/entity/NoteEntity.kt b/data/src/main/java/com/itlab/data/entity/NoteEntity.kt new file mode 100644 index 0000000..198c96a --- /dev/null +++ b/data/src/main/java/com/itlab/data/entity/NoteEntity.kt @@ -0,0 +1,21 @@ +package com.itlab.data.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import kotlinx.datetime.Instant + +@Entity(tableName = "notes") +data class NoteEntity( + @PrimaryKey + val id: String, + val title: String, + val content: String, + val folderId: String? = null, + val createdAt: Instant, + val updatedAt: Instant, + val tags: String? = null, + val isFavorite: Boolean = false, + val isSynced: Boolean = false, + val isDeleted: Boolean = false, + val summary: String? = null, +) diff --git a/data/src/main/java/com/itlab/data/mapper/NoteFolderMapper.kt b/data/src/main/java/com/itlab/data/mapper/NoteFolderMapper.kt new file mode 100644 index 0000000..9980cf3 --- /dev/null +++ b/data/src/main/java/com/itlab/data/mapper/NoteFolderMapper.kt @@ -0,0 +1,32 @@ +package com.itlab.data.mapper + +import com.itlab.data.entity.FolderEntity +import com.itlab.domain.model.NoteFolder + +class NoteFolderMapper { + fun toEntity(folder: NoteFolder): FolderEntity { + val entityFolder = + FolderEntity( + id = folder.id, + name = folder.name, + createdAt = folder.createdAt, + updatedAt = folder.updatedAt, + metadata = folder.metadata, + ) + + return entityFolder + } + + fun toDomain(entity: FolderEntity): NoteFolder { + val noteFolder = + NoteFolder( + id = entity.id, + name = entity.name, + createdAt = entity.createdAt, + updatedAt = entity.updatedAt, + metadata = entity.metadata, + ) + + return noteFolder + } +} diff --git a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt new file mode 100644 index 0000000..5033a15 --- /dev/null +++ b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt @@ -0,0 +1,95 @@ +package com.itlab.data.mapper + +import com.itlab.data.entity.MediaEntity +import com.itlab.data.entity.NoteEntity +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.Note +import kotlinx.serialization.SerializationException +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import timber.log.Timber +import java.util.UUID + +class NoteMapper( + private val json: Json = + Json { + ignoreUnknownKeys = true + encodeDefaults = true + }, +) { + fun toEntities(note: Note): Pair> { + val noteId = note.id + + val mediaEntities = + note.contentItems.mapNotNull { item -> + toMediaEntity(item, noteId) + } + + val noteEntity = + NoteEntity( + id = noteId, + title = note.title, + folderId = note.folderId, + content = json.encodeToString(note.contentItems), + createdAt = note.createdAt, + updatedAt = note.updatedAt, + tags = json.encodeToString(note.tags), + isFavorite = note.isFavorite, + isSynced = false, + summary = note.summary, + ) + + return noteEntity to mediaEntities + } + + fun toDomain(entity: NoteEntity): Note { + val items = + try { + json.decodeFromString>(entity.content) + } catch (e: SerializationException) { + Timber.e(e, "Note content mapping failed for entity: ${entity.id}") + emptyList() + } + + val tags = + try { + json.decodeFromString>(entity.tags ?: "[]") + } catch (e: SerializationException) { + Timber.e(e, "Tags mapping failed for note ${entity.id}. Raw data: ${entity.tags}") + emptySet() + } + + return Note( + id = entity.id, + title = entity.title, + contentItems = items, + folderId = entity.folderId, + createdAt = entity.createdAt, + updatedAt = entity.updatedAt, + tags = tags, + isFavorite = entity.isFavorite, + ) + } + + private fun toMediaEntity( + item: ContentItem, + noteId: String, + ): MediaEntity? { + val (source, type, mimeType) = + when (item) { + is ContentItem.Image -> Triple(item.source, "IMAGE", item.mimeType) + is ContentItem.File -> Triple(item.source, "FILE", item.mimeType) + else -> return null + } + + return MediaEntity( + id = UUID.randomUUID().toString(), + noteId = noteId, + type = type, + remoteUrl = source.remoteUrl, + localPath = source.localPath, + mimeType = mimeType, + size = (item as? ContentItem.File)?.size, + ) + } +} diff --git a/data/src/main/java/com/itlab/data/repository/NoteFolderRepositoryImpl.kt b/data/src/main/java/com/itlab/data/repository/NoteFolderRepositoryImpl.kt new file mode 100644 index 0000000..e711771 --- /dev/null +++ b/data/src/main/java/com/itlab/data/repository/NoteFolderRepositoryImpl.kt @@ -0,0 +1,45 @@ +package com.itlab.data.repository + +import com.itlab.data.dao.FolderDao +import com.itlab.data.mapper.NoteFolderMapper +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class NoteFolderRepositoryImpl( + private val folderDao: FolderDao, + private val mapper: NoteFolderMapper, +) : NoteFolderRepository { + override suspend fun createFolder(folder: NoteFolder): String { + folderDao.insert(mapper.toEntity(folder)) + return folder.id + } + + override fun observeFolders(): Flow> = + folderDao.getAllFolders().map { entities -> + entities.map { mapper.toDomain(it) } + } + + override suspend fun renameFolder( + id: String, + name: String, + ) { + folderDao.updateName(id, name) + } + + override suspend fun deleteFolder(id: String) { + folderDao.getFolderById(id)?.let { + folderDao.delete(it) + } + } + + override suspend fun getFolderById(id: String): NoteFolder? = + folderDao.getFolderById(id)?.let { + mapper.toDomain(it) + } + + override suspend fun updateFolder(folder: NoteFolder) { + folderDao.update(mapper.toEntity(folder)) + } +} diff --git a/data/src/main/java/com/itlab/data/repository/NotesRepositoryImpl.kt b/data/src/main/java/com/itlab/data/repository/NotesRepositoryImpl.kt index f9a734f..44e2d48 100644 --- a/data/src/main/java/com/itlab/data/repository/NotesRepositoryImpl.kt +++ b/data/src/main/java/com/itlab/data/repository/NotesRepositoryImpl.kt @@ -1,3 +1,49 @@ package com.itlab.data.repository -class NotesRepositoryImpl +import com.itlab.data.dao.MediaDao +import com.itlab.data.dao.NoteDao +import com.itlab.data.mapper.NoteMapper +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class NotesRepositoryImpl( + private val noteDao: NoteDao, + private val mediaDao: MediaDao, + private val mapper: NoteMapper, +) : NotesRepository { + override fun observeNotes(): Flow> = + noteDao.getAllNotes().map { entities -> + entities.map { mapper.toDomain(it) } + } + + override fun observeNotesByFolder(folderId: String): Flow> = + noteDao.getNotesByFolder(folderId).map { entities -> + entities.map { mapper.toDomain(it) } + } + + override suspend fun getNoteById(id: String): Note? = + noteDao.getNoteByld(id)?.let { + mapper.toDomain(it) + } + + override suspend fun createNote(note: Note): String { + val (notesEntity, mediaEntities) = mapper.toEntities(note) + noteDao.insert(notesEntity) + if (mediaEntities.isNotEmpty()) mediaDao.insertAll(mediaEntities) + return note.id + } + + override suspend fun updateNote(note: Note) { + val (noteEntity, mediaEntities) = mapper.toEntities(note) + noteDao.update(noteEntity) + + mediaDao.deleteByNoteId(note.id) + if (mediaEntities.isNotEmpty()) mediaDao.insertAll(mediaEntities) + } + + override suspend fun deleteNote(id: String) { + noteDao.getNoteByld(id)?.let { noteDao.delete(it) } + } +} diff --git a/data/src/test/java/com/itlab/data/ExampleUnitTest.kt b/data/src/test/java/com/itlab/data/ExampleUnitTest.kt deleted file mode 100644 index fa860ea..0000000 --- a/data/src/test/java/com/itlab/data/ExampleUnitTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.itlab.data - -import com.itlab.data.repository.NotesRepositoryImpl -import com.itlab.data.storage.FileStorage -import com.itlab.data.storage.JsonMapper -import org.junit.Assert.assertNotNull -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun createsDataComponents() { - assertNotNull(NotesRepositoryImpl()) - assertNotNull(FileStorage()) - assertNotNull(JsonMapper()) - } -} diff --git a/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt b/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt new file mode 100644 index 0000000..d88e3a6 --- /dev/null +++ b/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt @@ -0,0 +1,147 @@ +package com.itlab.data.dao + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.itlab.data.db.AppDatabase +import com.itlab.data.entity.MediaEntity +import com.itlab.data.entity.NoteEntity +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Instant +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(manifest = Config.NONE) +class MediaDaoTest { + private lateinit var database: AppDatabase + private lateinit var mediaDao: MediaDao + private lateinit var noteDao: NoteDao + + val testTime = Instant.parse("2026-03-24T12:00:00Z") + + private suspend fun insertParentNote(id: String) { + val note = + com.itlab.data.entity.NoteEntity( + id = id, + title = "Parent Note", + content = "Content", + createdAt = testTime, + updatedAt = kotlinx.datetime.Instant.fromEpochMilliseconds(0), + isSynced = true, + ) + noteDao.insert(note) + } + + private val defaultPath = """C:\Users\egoru\Downloads\Blazhin_-_Ne_perebivajj_64351892.mp3""" + + private fun createMedia( + id: String, + noteId: String, + type: String = "audio", + localPath: String? = defaultPath, + remoteUrl: String? = null, + ) = MediaEntity( + id = id, + noteId = noteId, + type = type, + remoteUrl = remoteUrl, + localPath = localPath, + mimeType = "audio/mpeg", + size = 1024L, + ) + + @Before + fun setup() { + database = + Room + .inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, + ).allowMainThreadQueries() + .build() + + mediaDao = database.mediaDao() + noteDao = database.noteDao() + } + + @After + fun cleanup() { + database.close() + } + + @Test + fun `insert and getMediaForNote should return correct media with paths`() = + runTest { + val noteId = "note1" + insertParentNote(noteId) + + val audioPath = defaultPath + val media = createMedia(id = "m1", noteId = "note1", localPath = audioPath) + + mediaDao.insert(media) + + val result = mediaDao.getMediaForNote("note1") + + assertEquals(1, result.size) + assertEquals(audioPath, result[0].localPath) + assertEquals("audio/mpeg", result[0].mimeType) + } + + @Test + fun `insertAll should handle list of media and replace on conflict`() = + runTest { + val noteId = "note1" + insertParentNote(noteId) + + val list = + listOf( + createMedia("m1", "note1"), + createMedia("m2", "note1"), + ) + + mediaDao.insertAll(list) + + val updatedMedia = createMedia("m1", "note1", remoteUrl = "https://s3.yandex.net/bucket/audio.mp3") + mediaDao.insertAll(listOf(updatedMedia)) + + val result = mediaDao.getMediaForNote("note1") + val m1 = result.find { it.id == "m1" } + + assertEquals(2, result.size) + assertEquals("https://s3.yandex.net/bucket/audio.mp3", m1?.remoteUrl) + } + + @Test + fun `getMediaForNoteFlow should notify about changes`() = + runTest { + val noteId = "note1" + insertParentNote(noteId) + + val media = createMedia("m1", "note1") + mediaDao.insert(media) + + val flowResult = mediaDao.getMediaForNoteFlow("note1").first() + assertEquals(1, flowResult.size) + } + + @Test + fun `delete should remove specific media entity`() = + runTest { + val noteId = "note1" + insertParentNote(noteId) + + val media = createMedia("m1", "note1") + mediaDao.insert(media) + mediaDao.delete(media) + + val result = mediaDao.getMediaForNote("note1") + assertTrue(result.isEmpty()) + } +} diff --git a/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt b/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt new file mode 100644 index 0000000..5da39f6 --- /dev/null +++ b/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt @@ -0,0 +1,147 @@ +package com.itlab.data.dao + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.itlab.data.db.AppDatabase +import com.itlab.data.entity.NoteEntity +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Instant +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(manifest = Config.NONE) +class NoteDaoTest { + private lateinit var database: AppDatabase + private lateinit var noteDao: NoteDao + + val testTime = Instant.parse("2026-03-24T12:00:00Z") + + private fun createNote( + id: String, + title: String, + updatedAt: Instant = Instant.fromEpochMilliseconds(0), + isSynced: Boolean = true, + ) = NoteEntity( + id = id, + title = title, + content = "Content", + createdAt = testTime, + updatedAt = updatedAt, + isSynced = isSynced, + ) + + @Before + fun setup() { + database = + Room + .inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, + ).allowMainThreadQueries() + .build() + + noteDao = database.noteDao() + } + + @After + fun cleanup() { + database.close() + } + + @Test + fun `insert and getNoteById should return correct note`() = + runTest { + val note = createNote("1", "Title 1") + noteDao.insert(note) + + val retrieved = noteDao.getNoteByld("1") + + assertNotNull(retrieved) + assertEquals(note.id, retrieved?.id) + assertEquals(note.title, retrieved?.title) + assertEquals(note.content, retrieved?.content) + assertEquals(note.isSynced, retrieved?.isSynced) + assertEquals(note.updatedAt.toEpochMilliseconds(), retrieved?.updatedAt?.toEpochMilliseconds()) + } + + @Test + fun `update should modify existing note`() = + runTest { + val note = createNote("1", "Original") + noteDao.insert(note) + + val updated = note.copy(title = "Updated") + noteDao.update(updated) + + val retrieved = noteDao.getNoteByld("1") + assertEquals("Updated", retrieved?.title) + } + + @Test + fun `delete should remove note from database`() = + runTest { + val note = createNote("1", "To be deleted") + noteDao.insert(note) + noteDao.delete(note) + + val retrieved = noteDao.getNoteByld("1") + assertNull(retrieved) + } + + @Test + fun `getAllNotes should return notes ordered by updatedAt descending`() = + runTest { + val oldNote = createNote("1", "Old", updatedAt = Instant.fromEpochMilliseconds(1000L)) + val newNote = createNote("2", "New", updatedAt = Instant.fromEpochMilliseconds(2000L)) + + noteDao.insert(oldNote) + noteDao.insert(newNote) + + val notes = noteDao.getAllNotes().first() + + assertEquals(2, notes.size) + assertEquals("2", notes[0].id) + assertEquals("1", notes[1].id) + } + + @Test + fun `insertAll should save multiple notes and replace on conflict`() = + runTest { + val note1 = createNote("1", "First") + val note2 = createNote("2", "Second") + + noteDao.insertAll(listOf(note1, note2)) + + val note1Updated = createNote("1", "First Updated") + noteDao.insertAll(listOf(note1Updated)) + + val notes = noteDao.getAllNotes().first() + assertEquals(2, notes.size) + assertTrue(notes.any { it.title == "First Updated" }) + } + + @Test + fun `getUnsyncedNotes should only return notes where isSynced is false`() = + runTest { + val synced = createNote("1", "Synced", isSynced = true) + val unsynced = createNote("2", "Unsynced", isSynced = false) + + noteDao.insert(synced) + noteDao.insert(unsynced) + + val result = noteDao.getUnsyncedNotes() + + assertEquals(1, result.size) + assertEquals("2", result[0].id) + } +} diff --git a/data/src/test/java/com/itlab/data/db/AppDatabaseTest.kt b/data/src/test/java/com/itlab/data/db/AppDatabaseTest.kt new file mode 100644 index 0000000..f3ce4ab --- /dev/null +++ b/data/src/test/java/com/itlab/data/db/AppDatabaseTest.kt @@ -0,0 +1,39 @@ +package com.itlab.data.db + +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.After +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.annotation.Config + +@RunWith(AndroidJUnit4::class) +@Config(manifest = Config.NONE, sdk = [34]) +class AppDatabaseTest { + private lateinit var db: AppDatabase + + @Before + fun createDb() { + db = + Room + .inMemoryDatabaseBuilder( + ApplicationProvider.getApplicationContext(), + AppDatabase::class.java, + ).allowMainThreadQueries() + .build() + } + + @After + fun claseDb() { + db.close() + } + + @Test + fun `database should provide all daos`() { + assertNotNull(db.noteDao()) + assertNotNull(db.mediaDao()) + } +} diff --git a/data/src/test/java/com/itlab/data/db/DateTimeConvertersTest.kt b/data/src/test/java/com/itlab/data/db/DateTimeConvertersTest.kt new file mode 100644 index 0000000..8d88e2b --- /dev/null +++ b/data/src/test/java/com/itlab/data/db/DateTimeConvertersTest.kt @@ -0,0 +1,28 @@ +package com.itlab.data.db + +import kotlinx.datetime.Instant +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test + +class DateTimeConvertersTest { + private val converters = DateTimeConverters() + + @Test + fun `fromTimestamp should convert long to instant and handle null`() { + val timestamp = 1711272000000L + val expected = Instant.fromEpochMilliseconds(timestamp) + + assertEquals(expected, converters.fromTimestamp(timestamp)) + assertNull(converters.fromTimestamp(null)) + } + + @Test + fun `dateToTimestamp should convert instant to long and handle null`() { + val timestamp = 1711272000000L + val instant = Instant.fromEpochMilliseconds(timestamp) + + assertEquals(timestamp, converters.dateToTimestamp(instant)) + assertNull(converters.dateToTimestamp(null)) + } +} diff --git a/data/src/test/java/com/itlab/data/db/MetadataConverterTest.kt b/data/src/test/java/com/itlab/data/db/MetadataConverterTest.kt new file mode 100644 index 0000000..6cfc436 --- /dev/null +++ b/data/src/test/java/com/itlab/data/db/MetadataConverterTest.kt @@ -0,0 +1,25 @@ +package com.itlab.data.db + +import org.junit.Assert.assertEquals +import org.junit.Test + +class MetadataConverterTest { + private val converter = MetadataConverter() + + @Test + fun `metadata map should be converted to json string and back`() { + val originalMap = mapOf("color" to "blue", "priority" to "high") + + val jsonString = converter.fromMetadata(originalMap) + val resultMap = converter.toMetadata(jsonString) + + assertEquals(originalMap, resultMap) + assertEquals("blue", resultMap["color"]) + } + + @Test + fun `invalid json should return empty map`() { + val result = converter.toMetadata("invalid_json") + assertEquals(0, result.size) + } +} diff --git a/data/src/test/java/com/itlab/data/entity/FolderEntityTest.kt b/data/src/test/java/com/itlab/data/entity/FolderEntityTest.kt new file mode 100644 index 0000000..c08aa2b --- /dev/null +++ b/data/src/test/java/com/itlab/data/entity/FolderEntityTest.kt @@ -0,0 +1,3 @@ +package com.itlab.data.entity + +class FolderEntityTest diff --git a/data/src/test/java/com/itlab/data/entity/MediaEntityTest.kt b/data/src/test/java/com/itlab/data/entity/MediaEntityTest.kt new file mode 100644 index 0000000..bf9e215 --- /dev/null +++ b/data/src/test/java/com/itlab/data/entity/MediaEntityTest.kt @@ -0,0 +1,63 @@ +package com.itlab.data.entity + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test + +class MediaEntityTest { + @Test + fun `when MediaEntity is created, all properties map correctly`() { + val media = + MediaEntity( + id = "media_1", + noteId = "note_1", + type = "image", + remoteUrl = "s3://bucket/image.jpg", + localPath = "test/path/image.jpg", + mimeType = "image/jpeg", + size = 2048L, + ) + + assertEquals("media_1", media.id) + assertEquals("note_1", media.noteId) + assertEquals("image", media.type) + assertEquals("s3://bucket/image.jpg", media.remoteUrl) + assertEquals("test/path/image.jpg", media.localPath) + assertEquals("image/jpeg", media.mimeType) + assertEquals(2048L, media.size) + } + + @Test + fun `when MediaEntity is created with null optional values, they are null`() { + val media = + MediaEntity( + id = "media_2", + noteId = "note_2", + type = "audio", + remoteUrl = "s3://bucket/audio.mp3", + localPath = null, + mimeType = "audio/mpeg", + ) + + assertNull(media.localPath) + assertNull(media.size) + } + + @Test + fun `media equality`() { + val m1 = MediaEntity("1", "n1", "img", "u", "p", "m") + val m2 = MediaEntity("1", "n1", "img", "u", "p", "m") + + assertEquals(m1, m2) + assertEquals(m1.hashCode(), m2.hashCode()) + assert(m1.toString().isNotEmpty()) + } + + @Test + fun `media copy with null path`() { + val media = MediaEntity("1", "n1", "img", "u", "path", "m") + val noPathMedia = media.copy(localPath = null) + + assertEquals(null, noPathMedia.localPath) + } +} diff --git a/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt b/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt new file mode 100644 index 0000000..22ca791 --- /dev/null +++ b/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt @@ -0,0 +1,113 @@ +package com.itlab.data.entity + +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class NoteEntityTest { + val testTime = Instant.parse("2026-03-24T12:00:00Z") + + @Test + fun `when NoteEntity is created with minimum args, default values are set correctly`() { + val note = + NoteEntity( + id = "note_1", + title = "Test Title", + content = "Test Content", + createdAt = testTime, + updatedAt = testTime, + summary = "about content", + ) + + assertEquals("note_1", note.id) + assertEquals("Test Title", note.title) + assertEquals("Test Content", note.content) + assertFalse(note.isSynced) + assertEquals(testTime, note.createdAt) + assertEquals(testTime, note.updatedAt) + assertEquals(note.summary, "about content") + } + + @Test fun `when NoteEntity is fully initialized, all fields match`() { + val customTime = Clock.System.now() + + val note = + NoteEntity( + id = "note_2", + title = "Title 2", + content = "Content 2", + createdAt = customTime, + updatedAt = customTime, + isSynced = true, + ) + + assertEquals(customTime, note.createdAt) + assertEquals(customTime, note.updatedAt) + assertTrue(note.isSynced) + } + + @Test + fun `note creation and properties`() { + val note = + NoteEntity( + id = "1", + title = "Title", + content = "Content", + createdAt = testTime, + updatedAt = testTime, + ) + assertEquals("1", note.id) + assertEquals("Title", note.title) + assertEquals(false, note.isSynced) + } + + @Test + fun `note equality and hashcode`() { + val id = "1" + val title = "A" + val content = "B" + val timestamp = kotlinx.datetime.Instant.fromEpochMilliseconds(123456789L) + + val note1 = + NoteEntity( + id = id, + title = title, + content = content, + isSynced = false, + createdAt = timestamp, + updatedAt = timestamp, + ) + val note2 = + NoteEntity( + id = id, + title = title, + content = content, + isSynced = false, + createdAt = timestamp, + updatedAt = timestamp, + ) + + assertEquals(note1, note2) + assertEquals(note1.hashCode(), note2.hashCode()) + } + + @Test + fun `note copy updates fields`() { + val note = + NoteEntity( + "1", + "Old", + "Text", + createdAt = testTime, + updatedAt = testTime, + ) + val updated = note.copy(title = "New", isSynced = true) + + assertEquals("New", updated.title) + assertEquals(true, updated.isSynced) + assertEquals("1", updated.id) + } +} diff --git a/data/src/test/java/com/itlab/data/mapper/NoteFolderMapperTest.kt b/data/src/test/java/com/itlab/data/mapper/NoteFolderMapperTest.kt new file mode 100644 index 0000000..efce60c --- /dev/null +++ b/data/src/test/java/com/itlab/data/mapper/NoteFolderMapperTest.kt @@ -0,0 +1,67 @@ +package com.itlab.data.mapper + +import com.itlab.data.entity.FolderEntity +import com.itlab.domain.model.NoteFolder +import kotlinx.datetime.Instant +import org.junit.Assert.assertEquals +import org.junit.Test + +class NoteFolderMapperTest { + val mapper = NoteFolderMapper() + val testTime = Instant.parse("2026-03-24T12:00:00Z") + + @Test + fun `toEntity should map model correctly`() { + val uiMetadata = + mapOf( + "color" to "#FF5733", + "icon" to "folder_shared", + "is_expanded" to "true", + "display_mode" to "grid", + ) + + val noteFolder = + NoteFolder( + name = "Personal", + createdAt = testTime, + updatedAt = testTime, + metadata = uiMetadata, + ) + + val entityFolder = mapper.toEntity(noteFolder) + + assertEquals(noteFolder.id, entityFolder.id) + assertEquals(noteFolder.name, entityFolder.name) + assertEquals(noteFolder.createdAt, entityFolder.createdAt) + assertEquals(noteFolder.updatedAt, entityFolder.updatedAt) + assertEquals(noteFolder.metadata, entityFolder.metadata) + } + + @Test + fun `toDomain should map entity correctly`() { + val uiMetadata = + mapOf( + "color" to "#FF5733", + "icon" to "folder_shared", + "is_expanded" to "true", + "display_mode" to "grid", + ) + + val entityFolder = + FolderEntity( + id = "test-id", + name = "Personal", + createdAt = testTime, + updatedAt = testTime, + metadata = uiMetadata, + ) + + val noteFolder = mapper.toDomain(entityFolder) + + assertEquals(noteFolder.id, entityFolder.id) + assertEquals(noteFolder.name, entityFolder.name) + assertEquals(noteFolder.createdAt, entityFolder.createdAt) + assertEquals(noteFolder.updatedAt, entityFolder.updatedAt) + assertEquals(noteFolder.metadata, entityFolder.metadata) + } +} diff --git a/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt new file mode 100644 index 0000000..e549755 --- /dev/null +++ b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt @@ -0,0 +1,164 @@ +package com.itlab.data.mapper + +import com.itlab.data.entity.NoteEntity +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.DataSource +import com.itlab.domain.model.Note +import kotlinx.datetime.Instant +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import org.junit.Test + +class NoteMapperTest { + private val mapper = NoteMapper() + val testTime = Instant.parse("2026-03-24T12:00:00Z") + + @Test + fun `toEntities should map all content types and media correctly`() { + val note = + Note( + title = "Business", + tags = setOf("money", "market"), + contentItems = + listOf( + ContentItem.Text("I have money"), + ContentItem.Image( + source = DataSource(localPath = "local/path"), + mimeType = "image/png", + ), + ContentItem.File( + source = DataSource(remoteUrl = "https://cloud.com/doc"), + mimeType = "application/pdf", + name = "doc.pdf", + size = 1024L, + ), + ContentItem.Link("https://google.com"), + ), + isFavorite = true, + summary = "cars", + ) + + val (entity, media) = mapper.toEntities(note) + + assertEquals(note.id, entity.id) + assertEquals("Business", entity.title) + assertTrue(entity.isFavorite) + assertFalse(entity.isSynced) + assertEquals(null, entity.folderId) + assertEquals(note.createdAt, entity.createdAt) + assertEquals(note.updatedAt, entity.updatedAt) + assertEquals(note.summary, entity.summary) + + assertEquals("[\"money\",\"market\"]", entity.tags) + + val decodedItems = Json.decodeFromString>(entity.content) + + assertEquals(note.contentItems, decodedItems) + + assertEquals(2, media.size) + + val image = media.find { it.type == "IMAGE" } + + assertNotNull(image?.id) + assertEquals(note.id, image?.noteId) + assertEquals("local/path", image?.localPath) + assertEquals(null, image?.remoteUrl) + assertEquals("image/png", image?.mimeType) + + val file = media.find { it.type == "FILE" } + assertNotNull(file?.id) + assertEquals(note.id, file?.noteId) + assertEquals("https://cloud.com/doc", file?.remoteUrl) + assertEquals(null, file?.localPath) + assertEquals("application/pdf", file?.mimeType) + assertEquals(1024L, file?.size) + } + + @Test + fun `toDomain should return empty lists when JSON is corrupted`() { + val corruptedEntity = + NoteEntity( + id = "test-id", + title = "Broken Note", + content = "!!not a json!!", + tags = "{broken_tags}", + createdAt = testTime, + updatedAt = testTime, + ) + + val result = mapper.toDomain(corruptedEntity) + + assertTrue(result.contentItems.isEmpty()) + assertTrue(result.tags.isEmpty()) + assertEquals("Broken Note", result.title) + } + + @Test + fun `toDomain should correctly restore Note from NoteEntity`() { + val originalItems = + listOf( + ContentItem.Text("First item"), + ContentItem.Link("https://itlab.com", "IT Lab"), + ContentItem.Image( + source = DataSource(localPath = "local/path"), + mimeType = "image/", + ), + ContentItem.File( + source = DataSource(remoteUrl = "https://cloud.com/doc"), + mimeType = "application/pdf", + name = "doc.pdf", + size = 1024L, + ), + ) + + val originalTags = setOf("android", "testing") + + val json = Json { ignoreUnknownKeys = true } + + val entity = + NoteEntity( + id = "uuid-123", + title = "Test Note", + folderId = "fuid-100", + content = json.encodeToString>(originalItems), + tags = json.encodeToString>(originalTags), + isFavorite = true, + createdAt = testTime, + updatedAt = testTime, + ) + + val resultNote = mapper.toDomain(entity) + + assertEquals("uuid-123", resultNote.id) + assertEquals("Test Note", resultNote.title) + assertEquals("fuid-100", resultNote.folderId) + assertTrue(resultNote.isFavorite) + + assertEquals(originalItems, resultNote.contentItems) + assertEquals(originalTags, resultNote.tags) + } + + @Test + fun `toDomain should handle null tags in NoteEntity by returning empty set`() { + val entityWithNullTags = + NoteEntity( + id = "test-null-tags", + title = "Note with NULL tags", + content = "[]", + tags = null, + folderId = null, + isFavorite = false, + createdAt = testTime, + updatedAt = testTime, + ) + + val resultNote = mapper.toDomain(entityWithNullTags) + + assertNotNull(resultNote.tags) + assertTrue(resultNote.tags.isEmpty()) + } +} diff --git a/data/src/test/java/com/itlab/data/repository/NoteFolderRepositoryImplTest.kt b/data/src/test/java/com/itlab/data/repository/NoteFolderRepositoryImplTest.kt new file mode 100644 index 0000000..e3e5d8e --- /dev/null +++ b/data/src/test/java/com/itlab/data/repository/NoteFolderRepositoryImplTest.kt @@ -0,0 +1,154 @@ +package com.itlab.data.repository + +import com.itlab.data.dao.FolderDao +import com.itlab.data.entity.FolderEntity +import com.itlab.data.mapper.NoteFolderMapper +import com.itlab.domain.model.NoteFolder +import io.mockk.Runs +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.just +import io.mockk.mockk +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Clock +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test + +class NoteFolderRepositoryImplTest { + private val folderDao = mockk(relaxed = true) + private val mapper = NoteFolderMapper() + private val repository = NoteFolderRepositoryImpl(folderDao, mapper) + + private val testFolder = + NoteFolder( + id = "1", + name = "Work", + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + metadata = emptyMap(), + ) + + @Test + fun `observeFolders emits mapped domain list`() = + runTest { + val entity = mapper.toEntity(testFolder) + coEvery { folderDao.getAllFolders() } returns flowOf(listOf(entity)) + + val result = repository.observeFolders().first() + + assertEquals(1, result.size) + assertEquals(testFolder.name, result[0].name) + } + + @Test + fun `renameFolder calls dao updateName`() = + runTest { + repository.renameFolder("1", "New Name") + coEvery { folderDao.updateName("1", "New Name") } + } + + @Test + fun `getFolderById returns mapped folder or null`() = + runTest { + coEvery { folderDao.getFolderById("1") } returns mapper.toEntity(testFolder) + coEvery { folderDao.getFolderById("2") } returns null + + assertEquals("Work", repository.getFolderById("1")?.name) + assertEquals(null, repository.getFolderById("2")) + } + + @Test + fun `observeFolders emits empty list when dao is empty`() = + runTest { + coEvery { folderDao.getAllFolders() } returns flowOf(emptyList()) + + val result = repository.observeFolders().first() + + assertTrue(result.isEmpty()) + } + + @Test + fun `deleteFolder does nothing if folder not found`() = + runTest { + coEvery { folderDao.getFolderById("999") } returns null + + repository.deleteFolder("999") + + coVerify(exactly = 0) { folderDao.delete(any()) } + } + + @Test + fun `updateFolder calls dao update`() = + runTest { + repository.updateFolder(testFolder) + coVerify { folderDao.update(any()) } + } + + @Test + fun `deleteFolder should skip deletion if folder does not exist`() = + runTest { + coEvery { folderDao.getFolderById("id") } returns null + + repository.deleteFolder("id") + + coVerify(exactly = 0) { folderDao.delete(any()) } + } + + @Test + fun `getFolderById returns null when dao returns null`() = + runTest { + coEvery { folderDao.getFolderById("any") } returns null + val result = repository.getFolderById("any") + assertNull(result) + } + + @Test + fun `deleteFolder handles missing folder`() = + runTest { + coEvery { folderDao.getFolderById("id") } returns null + + repository.deleteFolder("id") + + coVerify(exactly = 0) { folderDao.delete(any()) } + } + + @Test + fun `renameFolder calls dao update`() = + runTest { + repository.renameFolder("folder_1", "New Name") + coVerify { folderDao.updateName("folder_1", "New Name") } + } + + @Test + fun `createFolder inserts entity and returns correct id`() = + runTest { + val folder = NoteFolder(id = "folder_777", name = "Test Folder") + + coEvery { folderDao.insert(any()) } just Runs + + val resultId = repository.createFolder(folder) + + coVerify { folderDao.insert(any()) } + assertEquals("folder_777", resultId) + } + + @Test + fun `deleteFolder calls dao delete when folder is found`() = + runTest { + val folderId = "target_id" + val entity = mockk(relaxed = true) + + // Возвращаем реальный объект, чтобы зайти внутрь ?.let + coEvery { folderDao.getFolderById(folderId) } returns entity + coEvery { folderDao.delete(entity) } just Runs + + repository.deleteFolder(folderId) + + // Эта проверка гасит красную строку `folderDao.delete(it)` + coVerify(exactly = 1) { folderDao.delete(entity) } + } +} diff --git a/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt b/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt new file mode 100644 index 0000000..2afec51 --- /dev/null +++ b/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt @@ -0,0 +1,245 @@ +package com.itlab.data.repository + +import com.itlab.data.dao.MediaDao +import com.itlab.data.dao.NoteDao +import com.itlab.data.entity.NoteEntity +import com.itlab.data.mapper.NoteMapper +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.DataSource +import com.itlab.domain.model.Note +import io.mockk.Runs +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.coVerifyOrder +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Clock +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test + +class NotesRepositoryImplTest { + private val noteDao = mockk(relaxed = true) + private val mediaDao = mockk(relaxed = true) + private val mapper = NoteMapper() + private val repository = NotesRepositoryImpl(noteDao, mediaDao, mapper) + + @Test + fun `createNote inserts note and media if exists`() = + runTest { + val note = + Note( + id = "note_1", + title = "Test", + contentItems = emptyList(), + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + ) + + repository.createNote(note) + + coEvery { noteDao.insert(any()) } + coVerify(exactly = 0) { mediaDao.insertAll(any()) } + } + + @Test + fun `updateNote cleans old media and inserts new`() = + runTest { + val note = + Note( + id = "note_1", + title = "Updated", + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + ) + + repository.updateNote(note) + + coVerifyOrder { + noteDao.update(any()) + mediaDao.deleteByNoteId("note_1") + } + } + + @Test + fun `deleteNote deletes by entity from dao`() = + runTest { + val noteId = "1" + coEvery { noteDao.getNoteByld(noteId) } returns mockk(relaxed = true) + + repository.deleteNote(noteId) + coVerify { noteDao.delete(any()) } + } + + @Test + fun `observeNotes emits mapped list from dao`() = + runTest { + val entities = listOf(mockk(relaxed = true)) + coEvery { noteDao.getAllNotes() } returns flowOf(entities) + + val result = repository.observeNotes().first() + + assertEquals(1, result.size) + coVerify { noteDao.getAllNotes() } + } + + @Test + fun `observeNotesByFolder emits filtered list`() = + runTest { + val folderId = "folder_x" + coEvery { noteDao.getNotesByFolder(folderId) } returns flowOf(emptyList()) + + val result = repository.observeNotesByFolder(folderId).first() + + assertTrue(result.isEmpty()) + coVerify { noteDao.getNotesByFolder(folderId) } + } + + @Test + fun `updateNote with media calls insertAll`() = + runTest { + val imageItem = + ContentItem.Image( + source = DataSource(localPath = "some/path", remoteUrl = null), + mimeType = "image/png", + ) + + val noteWithMedia = + Note( + id = "note_123", + title = "Note with Image", + contentItems = listOf(imageItem), + createdAt = Clock.System.now(), + updatedAt = Clock.System.now(), + ) + + repository.updateNote(noteWithMedia) + + coVerify { noteDao.update(any()) } + coVerify { mediaDao.deleteByNoteId("note_123") } + coVerify { mediaDao.insertAll(any()) } + } + + @Test + fun `updateNote without media should only call update and delete`() = + runTest { + val noteWithoutMedia = Note(id = "2", title = "No Media", contentItems = emptyList()) + + repository.updateNote(noteWithoutMedia) + + coVerify { noteDao.update(any()) } + coVerify { mediaDao.deleteByNoteId("2") } + coVerify(exactly = 0) { mediaDao.insertAll(any()) } + } + + @Test + fun `deleteNote does nothing if note not found`() = + runTest { + coEvery { noteDao.getNoteByld("non_existent") } returns null + + repository.deleteNote("non_existent") + + coVerify(exactly = 0) { noteDao.delete(any()) } + } + + @Test + fun `getNoteById returns null correctly`() = + runTest { + coEvery { noteDao.getNoteByld("any") } returns null + val result = repository.getNoteById("any") + assertNull(result) + } + + @Test + fun `deleteNote should not call dao delete if note is null`() = + runTest { + coEvery { noteDao.getNoteByld("missing_id") } returns null + + repository.deleteNote("missing_id") + + coVerify(exactly = 0) { noteDao.delete(any()) } + } + + @Test + fun `observeNotesByFolder emits empty list and then content`() = + runTest { + val folderId = "folder_1" + val flow = MutableStateFlow>(emptyList()) + coEvery { noteDao.getNotesByFolder(folderId) } returns flow + + val firstResult = repository.observeNotesByFolder(folderId).first() + assertTrue(firstResult.isEmpty()) + + val entity = + mockk(relaxed = true) { + every { id } returns "n1" + } + flow.value = listOf(entity) + val secondResult = repository.observeNotesByFolder(folderId).first() + assertEquals(1, secondResult.size) + } + + @Test + fun `observeNotes emits list when dao has data`() = + runTest { + val entity = mockk(relaxed = true) + coEvery { noteDao.getAllNotes() } returns flowOf(listOf(entity)) + + val result = repository.observeNotes().first() + + assertEquals(1, result.size) + } + + @Test + fun `deleteNote handles missing note gracefully`() = + runTest { + coEvery { noteDao.getNoteByld("unknown") } returns null + + repository.deleteNote("unknown") + + coVerify(exactly = 0) { noteDao.delete(any()) } + } + + @Test + fun `getNoteById returns mapped domain note when entity exists`() = + runTest { + val noteId = "note_123" + val entity = mockk(relaxed = true) + + coEvery { noteDao.getNoteByld(noteId) } returns entity + + val result = repository.getNoteById(noteId) + + assertNotNull(result) + } + + @Test + fun `saveNote inserts media entities when note has media`() = + runTest { + val imageItem = + ContentItem.Image( + source = DataSource(localPath = "local/path.jpg", remoteUrl = null), + mimeType = "image/jpeg", + ) + val noteWithMedia = + Note( + id = "note_with_pic", + title = "Vacation", + contentItems = listOf(imageItem), + ) + + coEvery { noteDao.insert(any()) } just Runs + coEvery { mediaDao.insertAll(any()) } just Runs + + repository.updateNote(noteWithMedia) + + coVerify(exactly = 1) { mediaDao.insertAll(any()) } + } +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..822fed8 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,17 @@ +# Documentation + +This directory contains developer-facing documentation for `openvino-notes`. + +## Documents + +- [Developer Guide](./developer/README.md) +- [Project Overview](./developer/project.md) +- [Local CI Reproduction](./developer/ci-local.md) + +## Scope + +These documents are written for contributors. They focus on: + +- project overview +- current implementation state +- local validation workflows diff --git a/docs/developer/README.md b/docs/developer/README.md new file mode 100644 index 0000000..517c6e1 --- /dev/null +++ b/docs/developer/README.md @@ -0,0 +1,226 @@ +# Developer Guide + +This documentation is intended for contributors working on `openvino-notes`. + +The repository already has a meaningful CI and build setup, while the application code is still at an early implementation stage. The goal of these documents is to help contributors understand the project quickly and reproduce the same checks that gate pull requests and `main`. + +## Recommended Reading Order + +1. [Local CI Reproduction](./ci-local.md) +2. [Project Overview](./project.md) + +## Current State + +What is already in place: + +- a four-module Android build +- reusable GitHub Actions workflows +- shared formatting, lint, and coverage policy + +What is still mostly scaffolded: + +- domain contracts +- data-layer behavior +- OpenVINO integration +- app-level product flows + +## Main Work Areas + +- Application code: `app`, `domain`, `data`, `ai` +- Automation and CI: `.github` + +# Domain Layer Documentation + +This documentation describes the Domain layer of the `openvino-notes` application. It is intended for contributors working on business logic, AI integration, and unit testing. + +The Domain layer is the central part of the architecture, defining business rules for notes and folders, AI operations, and repository contracts. It is independent of storage, UI, and AI implementation details. + +## Purpose + +- Maintain business logic separately from UI, storage, and AI. +- Define domain entities, repository contracts, and use cases. +- Provide testable interfaces for both normal and AI-enhanced operations. + +## Layer Responsibilities + +The Domain layer contains: + +- Domain models (`Note`, `NoteFolder`) +- Repository interfaces (`NotesRepository`, `NoteFolderRepository`) +- Use cases for notes and folders +- AI service interface (`NoteAiService`) +- AI-related use cases (`SuggestSummaryUseCase`, `ApplyTagsUseCase`, etc.) + +The Domain layer **does not contain**: + +- UI elements or ViewModels +- Android-specific code +- Implementation details of repositories or AI +- OpenVINO or network code + +## Structure +domain/ +├─ ai/ +│ └─ NoteAiService.kt +├─ aiusecase/ +│ ├─ ApplySummaryUseCase.kt +│ ├─ ApplyTagsUseCase.kt +│ ├─ SuggestSummaryUseCase.kt +│ └─ SuggestTagsUseCase.kt +├─ model/ +│ ├─ Note.kt +│ ├─ NoteFolder.kt +│ └─ ContentItem.kt +├─ repository/ +│ ├─ NotesRepository.kt +│ └─ NoteFolderRepository.kt +└─ usecase/ +├─ CreateNoteUseCase.kt +├─ DeleteNoteUseCase.kt +├─ GetNoteUseCase.kt +├─ UpdateNoteUseCase.kt +└─ MoveNoteToFolderUseCase.kt + + +## Domain Models + +### Note + +- `id`: unique identifier +- `title`: note title +- `folderId`: optional folder ID +- `contentItems`: list of `ContentItem` +- `createdAt`: creation timestamp +- `updatedAt`: last update timestamp +- `tags`: set of tags +- `isFavorite`: favorite flag +- `summary`: optional AI-generated summary + +### ContentItem + +Sealed class representing a note's content: + +- `Text`: text block +- `Image`: image block (`Local` or `Remote` source) +- `File`: file attachment +- `Link`: URL link + +### TextFormat + +- `PLAIN`, `MARKDOWN`, `HTML` + +### ImageSource + +- `Local`: local file path +- `Remote`: remote URL + +### NoteFolder + +- `id`: unique identifier +- `name`: folder name +- `createdAt`, `updatedAt`: timestamps +- `metadata`: optional extra info + +## Repository Interfaces + +### NotesRepository + +- `observeNotes()`: flow of all notes +- `observeNotesByFolder(folderId)`: flow of notes for a folder +- `getNoteById(id)`: retrieve note by ID +- `createNote(note)`: create note +- `updateNote(note)`: update note +- `deleteNote(id)`: delete note + +### NoteFolderRepository + +- `observeFolders()`: flow of folders +- `createFolder(folder)`: create folder +- `renameFolder(id, name)`: rename folder +- `deleteFolder(id)`: delete folder +- `getFolderById(id)`: retrieve folder by ID +- `updateFolder(folder)`: update folder + +Repositories abstract storage for testable domain logic. + +## Use Cases + +### Folder Use Cases + +- `CreateFolderUseCase` +- `DeleteFolderUseCase` +- `GetFolderUseCase` +- `ObserveFoldersUseCase` +- `UpdateFolderUseCase` + +### Note Use Cases + +- `CreateNoteUseCase` +- `DeleteNoteUseCase` +- `GetNoteUseCase` +- `UpdateNoteUseCase` +- `MoveNoteToFolderUseCase` +- `ObserveNotesUseCase` +- `ObserveNotesByFolderUseCase` + +## AI Contract + +### NoteAiService + +Interface for AI operations. + +- `suspend fun summarize(text: String): String` +- `suspend fun tagTXT(text: String): Set` +- `suspend fun tagIMGs(images: List): Set` + +## AI Use Cases + +- `SuggestSummaryUseCase`: extract text, call AI, return proposed summary +- `SuggestTagsUseCase`: extract text/images, call AI, return combined tags +- `ApplySummaryUseCase`: update note with AI-generated summary +- `ApplyTagsUseCase`: update note with AI-generated tags + +AI operations are separated into **suggest** (proposal) and **apply** (commit) stages. + +## Data Flow + +### Normal Note Operations + +1. UI triggers an action +2. ViewModel calls a use case +3. Use case interacts with repository +4. Repository returns or saves domain models +5. Result propagates back to ViewModel +6. ViewModel updates UI + +### AI Operations + +1. UI triggers AI action +2. ViewModel calls `SuggestSummaryUseCase` or `SuggestTagsUseCase` +3. Use case retrieves note from repository +4. Use case extracts content +5. Use case calls `NoteAiService` +6. AI returns results +7. ViewModel receives results +8. If confirmed, `ApplySummaryUseCase` or `ApplyTagsUseCase` updates the note + +## Principles + +- Android-agnostic +- Storage-agnostic +- AI-implementation-agnostic +- “Suggest” and “Apply” AI operations are separated +- Models are extensible + +## Testing + +Unit tests cover: + +- Creating, updating, deleting notes and folders +- Moving notes between folders +- Observing notes and folders +- Getting AI-generated summaries and tags +- Applying summaries and tags +- Error handling for missing notes + +Fake repositories and fake AI service enable testing without Android or OpenVINO dependencies. \ No newline at end of file diff --git a/docs/developer/ci-local.md b/docs/developer/ci-local.md new file mode 100644 index 0000000..bd8bbf3 --- /dev/null +++ b/docs/developer/ci-local.md @@ -0,0 +1,414 @@ +# Local CI Reproduction + +This guide explains how to reproduce repository checks locally on Linux, macOS, and Windows. + +## Toolchain Baseline + +- JDK 17 +- Android SDK command-line tools +- Android platform-tools +- Android platform `android-36` +- Android build-tools `36.0.0` +- Git + +## Validation Status + +### macOS arm64 + +Validated locally: + +- foundation checks +- debug build and unit tests +- coverage +- release assemble +- release lint +- CodeQL build +- preflight +- APK task validation +- gitleaks +- emulator instrumentation + +Environment used: + +- Homebrew `openjdk@17` +- Android SDK root: `~/Library/Android/sdk` +- emulator target: `android-34`, `google_apis`, `arm64-v8a` + +### Linux arm64 + +Validated locally on Ubuntu 24.04 arm64: + +- JDK 17 setup +- Android SDK command-line tools setup +- `sdkmanager` package install +- preflight + +Observed differences: + +- if `local.properties` points to an SDK path from another OS, Gradle prefers it over `ANDROID_SDK_ROOT` +- `.github/scripts/security/run_gitleaks.sh` fails on arm64 because it downloads a `linux_x64` binary +- Android lint/build path failed with `Aapt2InternalException: Failed to start AAPT2 process` + +### Linux x86_64 + +This is the closest path to GitHub CI and should be treated as the reference Linux environment for full parity. + +## Environment Setup + +### macOS + +```bash +export JAVA_HOME="$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home" +export PATH="$JAVA_HOME/bin:$PATH" +export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk" +export ANDROID_HOME="$ANDROID_SDK_ROOT" +export ANDROID_API_LEVEL=36 +export ANDROID_BUILD_TOOLS=36.0.0 +export INSTALL_SYSTEM_IMAGE=false +export ANDROID_SYSTEM_IMAGE= + +bash .github/scripts/setup/install_android_sdk_packages.sh +``` + +### Linux + +```bash +export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +export PATH="$JAVA_HOME/bin:$PATH" +export ANDROID_SDK_ROOT="$HOME/Android/Sdk" +export ANDROID_HOME="$ANDROID_SDK_ROOT" +export ANDROID_API_LEVEL=36 +export ANDROID_BUILD_TOOLS=36.0.0 +export INSTALL_SYSTEM_IMAGE=false +export ANDROID_SYSTEM_IMAGE= + +bash .github/scripts/setup/install_android_sdk_packages.sh +``` + +If your Linux host is `arm64`, native SDK installation can still work, but Android Gradle tasks may differ from `x86_64` CI behavior. + +### Windows PowerShell + +```powershell +$env:ANDROID_API_LEVEL = "36" +$env:ANDROID_BUILD_TOOLS = "36.0.0" +$env:INSTALL_SYSTEM_IMAGE = "false" +$env:ANDROID_SYSTEM_IMAGE = "" + +.\.github\scripts\setup\install_android_sdk_packages_windows.ps1 +``` + +## Cross-OS SDK Path Note + +If the working tree was copied from another machine or another OS, check `local.properties`. + +If it contains a stale `sdk.dir`, Gradle uses that value before `ANDROID_SDK_ROOT`. + +Fix it with: + +```bash +printf 'sdk.dir=%s\n' "$HOME/Android/Sdk" > local.properties +``` + +On macOS: + +```bash +printf 'sdk.dir=%s\n' "$HOME/Library/Android/sdk" > local.properties +``` + +## Main Local Gate + +Use this as the default pre-push validation path. + +### Linux or macOS + +```bash +bash .github/scripts/quality/run_foundation.sh +bash .github/scripts/quality/run_debug_build_and_unit_tests.sh +bash .github/scripts/quality/run_coverage.sh +``` + +### Windows PowerShell + +```powershell +.\.github\scripts\quality\run_debug_build_and_unit_tests_windows.ps1 + +.\gradlew.bat ktlintCheck detekt ai:lintDebug app:lintDebug data:lintDebug domain:lintDebug ai:testDebugUnitTest app:testDebugUnitTest data:testDebugUnitTest domain:testDebugUnitTest koverXmlReport koverVerify --stacktrace +``` + +## Checks + +### Foundation + +CI script: [run_foundation.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/quality/run_foundation.sh) + +Tasks: + +- `ktlintCheck` +- `detekt` +- `ai:lintDebug` +- `app:lintDebug` +- `data:lintDebug` +- `domain:lintDebug` + +Linux or macOS: + +```bash +bash .github/scripts/quality/run_foundation.sh +``` + +Windows: + +```powershell +.\gradlew.bat ktlintCheck detekt ai:lintDebug app:lintDebug data:lintDebug domain:lintDebug --stacktrace +``` + +Outputs: + +- `**/build/reports/detekt/` +- `**/build/reports/ktlint/` +- `**/build/reports/lint-results-*.html` +- `**/build/reports/lint-results-*.xml` + +Linux arm64 note: + +- on Ubuntu 24.04 arm64, the Android lint/build path failed with `Aapt2InternalException: Failed to start AAPT2 process` + +### Debug Build and Host Unit Tests + +CI scripts: + +- [run_debug_build_and_unit_tests.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/quality/run_debug_build_and_unit_tests.sh) +- [run_debug_build_and_unit_tests_windows.ps1](/Users/anesterov/repos/openvino-notes/.github/scripts/quality/run_debug_build_and_unit_tests_windows.ps1) + +Tasks: + +- `ai:assembleDebug` +- `app:assembleDebug` +- `app:assembleDebugAndroidTest` +- `data:assembleDebug` +- `domain:assembleDebug` +- `ai:testDebugUnitTest` +- `app:testDebugUnitTest` +- `data:testDebugUnitTest` +- `domain:testDebugUnitTest` + +Linux or macOS: + +```bash +bash .github/scripts/quality/run_debug_build_and_unit_tests.sh +``` + +Windows: + +```powershell +.\.github\scripts\quality\run_debug_build_and_unit_tests_windows.ps1 +``` + +Outputs: + +- `app/build/outputs/apk/debug/app-debug.apk` +- `app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk` +- `**/build/test-results/` +- `**/build/reports/tests/` +- `**/build/outputs/unit_test_code_coverage/` + +### Coverage + +CI script: [run_coverage.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/quality/run_coverage.sh) + +Tasks: + +- `ai:testDebugUnitTest` +- `app:testDebugUnitTest` +- `data:testDebugUnitTest` +- `domain:testDebugUnitTest` +- `koverXmlReport` +- `koverVerify` + +Linux or macOS: + +```bash +bash .github/scripts/quality/run_coverage.sh +``` + +Windows: + +```powershell +.\gradlew.bat ai:testDebugUnitTest app:testDebugUnitTest data:testDebugUnitTest domain:testDebugUnitTest koverXmlReport koverVerify --stacktrace +``` + +Output: + +- `**/build/reports/kover/` + +### Release + +CI scripts: + +- [assemble_release.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/release/assemble_release.sh) +- [lint_release.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/release/lint_release.sh) + +Linux or macOS: + +```bash +bash .github/scripts/release/assemble_release.sh +bash .github/scripts/release/lint_release.sh +``` + +Windows: + +```powershell +.\gradlew.bat ai:assembleRelease app:assembleRelease data:assembleRelease domain:assembleRelease --stacktrace +.\gradlew.bat ai:lintRelease app:lintRelease data:lintRelease domain:lintRelease --stacktrace +``` + +### Secrets + +CI script: [run_gitleaks.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/security/run_gitleaks.sh) + +Linux x86_64: + +```bash +bash .github/scripts/security/run_gitleaks.sh +``` + +Native `gitleaks` path for Linux arm64, macOS, and Windows: + +```bash +gitleaks detect --source . --report-format sarif --report-path build/reports/gitleaks/gitleaks.sarif --redact +``` + +Linux arm64 note: + +- `.github/scripts/security/run_gitleaks.sh` failed with `cannot execute binary file: Exec format error` + +### Preflight + +CI script: [classify_changes.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/preflight/classify_changes.sh) + +The script expects `GITHUB_OUTPUT`, so a plain local invocation is not enough. + +Example: + +```bash +tmpfile="$(mktemp)" +GITHUB_OUTPUT="$tmpfile" \ +EVENT_NAME=pull_request \ +BASE_SHA="$(git merge-base upstream/main HEAD)" \ +HEAD_SHA="$(git rev-parse HEAD)" \ +BEFORE_SHA="" \ +CURRENT_SHA="$(git rev-parse HEAD)" \ +bash .github/scripts/preflight/classify_changes.sh +cat "$tmpfile" +rm -f "$tmpfile" +``` + +### CodeQL Build + +CI script: [build_for_codeql.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/codeql/build_for_codeql.sh) + +Linux or macOS: + +```bash +bash .github/scripts/codeql/build_for_codeql.sh +``` + +Windows: + +```powershell +.\gradlew.bat clean ai:assembleDebug app:assembleDebug data:assembleDebug domain:assembleDebug --no-build-cache --rerun-tasks --stacktrace +``` + +Limitation: + +- this reproduces the build input +- full local parity still requires local CodeQL CLI setup + +### Android Instrumentation + +CI scripts: + +- [validate_debug_apk_tasks.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/android/validate_debug_apk_tasks.sh) +- [run_emulator_instrumentation.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/android/run_emulator_instrumentation.sh) +- [run_all_instrumentation_variants.sh](/Users/anesterov/repos/openvino-notes/.github/scripts/android/run_all_instrumentation_variants.sh) + +GitHub CI target: + +- Linux +- API 34 +- `x86_64` +- `pixel_7` + +Validated local macOS target: + +- macOS arm64 +- API 34 +- `arm64-v8a` +- `pixel_7` + +Linux arm64 status: + +- not validated end-to-end +- upstream Android build path already failed at AAPT2 startup + +Task validation: + +Linux or macOS: + +```bash +bash .github/scripts/android/validate_debug_apk_tasks.sh +``` + +Windows: + +```powershell +.\gradlew.bat app:assembleDebug app:assembleDebugAndroidTest -m --stacktrace +``` + +Basic manual flow: + +```bash +./gradlew app:assembleDebug app:assembleDebugAndroidTest --stacktrace +APK_DIR=app/build/outputs/apk bash .github/scripts/android/run_emulator_instrumentation.sh +``` + +Validated macOS arm64 flow: + +```bash +export JAVA_HOME="$(brew --prefix openjdk@17)/libexec/openjdk.jdk/Contents/Home" +export PATH="$JAVA_HOME/bin:$PATH:$HOME/Library/Android/sdk/emulator:$HOME/Library/Android/sdk/platform-tools" +export ANDROID_SDK_ROOT="$HOME/Library/Android/sdk" +export ANDROID_HOME="$ANDROID_SDK_ROOT" + +printf 'no\n' | avdmanager create avd -n pixel7api34Arm64Local -k 'system-images;android-34;google_apis;arm64-v8a' -d 'pixel_7' +./gradlew app:assembleDebug app:assembleDebugAndroidTest --stacktrace +emulator -avd pixel7api34Arm64Local -no-snapshot-save -no-window -noaudio -no-boot-anim -gpu swiftshader_indirect & +adb wait-for-device +until [ "$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" = "1" ]; do sleep 5; done +ANDROID_SERIAL=emulator-5554 APK_DIR=app/build/outputs/apk bash .github/scripts/android/run_emulator_instrumentation.sh +adb -s emulator-5554 emu kill +``` + +Validated result: + +```text +com.itlab.notes.ExampleInstrumentedTest:. + +Time: 0.006 + +OK (1 test) +``` + +## Not Fully Reproducible Locally + +- dependency review +- workflow summaries +- artifact upload +- full CodeQL action lifecycle + +## Practical Rule + +For pre-push debugging, reproducing the Gradle tasks and repository scripts above is usually enough. + +On Windows, use Git Bash or WSL for the bash-based Android helper scripts. The Gradle commands themselves are platform-specific, but the repository's emulator helper scripts are shell scripts, not PowerShell scripts. diff --git a/docs/developer/project.md b/docs/developer/project.md new file mode 100644 index 0000000..9e51dbd --- /dev/null +++ b/docs/developer/project.md @@ -0,0 +1,40 @@ +# Project Overview + +`openvino-notes` is an Android multi-module project. The product direction is an AI-assisted notes app powered by OpenVINO, but the repository is still at an early implementation stage. + +## Modules + +| Module | Responsibility | Current state | +| --- | --- | --- | +| `:app` | Android app module, Compose UI, and app wiring | Basic shell, starter UI, and debug and androidTest APK outputs | +| `:domain` | Models, repository contracts, and use cases | Mostly placeholder contracts and use cases | +| `:data` | Repository implementations, storage, and mapping | Structure exists, implementation is still minimal | +| `:ai` | OpenVINO-facing inference and result processing | Integration points exist, production behavior is not implemented yet | + +## Build and Automation + +- Root build logic lives in [build.gradle.kts](/Users/anesterov/repos/openvino-notes/build.gradle.kts). +- Shared configuration lives in [settings.gradle.kts](/Users/anesterov/repos/openvino-notes/settings.gradle.kts), [gradle.properties](/Users/anesterov/repos/openvino-notes/gradle.properties), [detekt.yml](/Users/anesterov/repos/openvino-notes/detekt.yml), and [lint.xml](/Users/anesterov/repos/openvino-notes/lint.xml). +- GitHub Actions workflows live in `.github/workflows/`. +- Most reusable command logic lives in `.github/scripts/`. + +## Current State + +Already in place: + +- a four-module Android build +- reusable GitHub Actions workflows +- shared formatting, lint, and coverage policy + +Still mostly scaffolded: + +- domain contracts +- data-layer behavior +- OpenVINO integration +- app-level product flows + +## Contributor Notes + +- Start with [Local CI Reproduction](./ci-local.md) for day-to-day validation commands. +- Check `.github/scripts/` before editing workflow YAML. +- If you change module boundaries, update Gradle settings, module build files, and docs together. diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 164c40d..f9bed20 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -1,12 +1,14 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.library) - alias(libs.plugins.kotlin.android) + kotlin("plugin.serialization") } android { namespace = "com.itlab.domain" compileSdk { - version = release(36) + version = release(37) } defaultConfig { @@ -29,8 +31,11 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } - kotlinOptions { - jvmTarget = "11" +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) } } @@ -41,4 +46,6 @@ dependencies { testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) + implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.serialization.json) } diff --git a/domain/gradle.lockfile b/domain/gradle.lockfile index da19f05..8189abf 100644 --- a/domain/gradle.lockfile +++ b/domain/gradle.lockfile @@ -1,84 +1,202 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -androidx.activity:activity:1.8.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat-resources:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.6.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-jvm:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.4.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-solver:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:2.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-ktx:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.17.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.dynamicanimation:dynamicanimation:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2-views-helper:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.3.6=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.6.2=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.profileinstaller:profileinstaller:1.3.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.2.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager2:viewpager2:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.android.material:material:1.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.intellij.deps:trove4j:1.0.20200330=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlin:kotlin-build-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-api:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-build-tools-impl:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-compiler-runner:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-client:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlin:kotlin-scripting-common:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-scripting-jvm:2.0.21=kotlinBuildToolsApiClasspath -org.jetbrains.kotlin:kotlin-stdlib:2.0.21=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kover-jvm-agent:0.9.1=koverJvmAgent -org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath -org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -empty=androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease,kotlinCompilerPluginClasspathReleaseUnitTest,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath +androidx.activity:activity:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-experimental:1.4.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.8.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.8.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat-resources:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat:1.6.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.appcompat:appcompat:1.7.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.arch.core:core-runtime:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-jvm:1.4.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.collection:collection:1.4.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.constraintlayout:constraintlayout-core:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.constraintlayout:constraintlayout-solver:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.0.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2:1.2.0=releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2:1.3.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.fragment:fragment:1.3.6=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.5.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-android:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.graphics:graphics-shapes:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.0=releaseUnitTestRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.3.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.ext:junit:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.services:storage:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:core:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath +androidx.tracing:tracing:1.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.2.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.transition:transition:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager2:viewpager2:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +ch.qos.logback:logback-classic:1.3.14=ktlint +ch.qos.logback:logback-core:1.3.14=ktlint +com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint +com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.material:material:1.10.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.android.material:material:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.15.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +com.google.guava:listenablefuture:1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-core:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-format:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-html:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-json:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain-summary:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-plain:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-reporter-sarif:1.5.0=ktlint +com.pinterest.ktlint:ktlint-cli-ruleset-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-cli:1.5.0=ktlint +com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset +com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint +com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations-jvm:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations-jvm:0.18.0=ktlint,ktlintRuleset +dev.drewhamilton.poko:poko-annotations:0.17.1=detekt +dev.drewhamilton.poko:poko-annotations:0.18.0=ktlint,ktlintRuleset +io.github.davidburstrom.contester:contester-breakpoint:0.2.0=detekt +io.github.detekt.sarif4k:sarif4k-jvm:0.6.0=detekt,ktlint,ktlintReporter +io.github.detekt.sarif4k:sarif4k:0.6.0=detekt,ktlint,ktlintReporter +io.github.oshai:kotlin-logging-jvm:7.0.3=ktlint,ktlintReporter,ktlintRuleset +io.github.oshai:kotlin-logging:5.1.0=ktlint,ktlintReporter +io.gitlab.arturbosch.detekt:detekt-api:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-cli:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-core:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-metrics:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-parser:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-psi-utils:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-html:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-md:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-sarif:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-txt:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-report-xml:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-complexity:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-coroutines:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-documentation:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-empty:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-errorprone:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-exceptions:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-naming:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-performance:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt +io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset +org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +org.jcommander:jcommander:1.85=detekt +org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-bom:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-build-tools-impl:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-compiler-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-compiler-runner:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-reflect:2.0.21=detekt +org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=detekt,kotlinCompilerClasspath +org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:2.3.20=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease +org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=detekt +org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.1.0=ktlint,ktlintReporter,ktlintRuleset +org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.1=detekt +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1=detekt,ktlintReporter +org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kover-jvm-agent:0.9.7=koverJvmAgent,koverJvmReporter +org.jetbrains:annotations:13.0=detekt,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintReporter,ktlintRuleset +org.jetbrains:annotations:23.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jspecify:jspecify:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.slf4j:slf4j-api:2.0.7=ktlint +org.snakeyaml:snakeyaml-engine:2.7=detekt +empty=androidApis,debugAnnotationProcessorClasspath,debugUnitTestAnnotationProcessorClasspath,detektPlugins,kotlinCompilerPluginClasspath,kotlinCompilerPluginClasspathReleaseUnitTest,koverExternalArtifacts,lintChecks,lintPublish,releaseAnnotationProcessorClasspath,releaseUnitTestAnnotationProcessorClasspath diff --git a/domain/src/main/java/com/itlab/domain/ai/NoteAiService.kt b/domain/src/main/java/com/itlab/domain/ai/NoteAiService.kt new file mode 100644 index 0000000..d6bf79a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/ai/NoteAiService.kt @@ -0,0 +1,9 @@ +package com.itlab.domain.ai + +interface NoteAiService { + suspend fun summarize(text: String): String + + suspend fun tagIMGs(img: List): Set + + suspend fun tagTXT(text: String): Set +} diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt b/domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt new file mode 100644 index 0000000..db484de --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt @@ -0,0 +1,26 @@ +package com.itlab.domain.aiusecase + +import com.itlab.domain.repository.NotesRepository + +class ApplySummaryUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke( + noteId: String, + newSummary: String, + ) { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found") + + val updated = + note.copy( + summary = newSummary, + updatedAt = + kotlinx.datetime.Clock.System + .now(), + ) + + repo.updateNote(updated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt b/domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt new file mode 100644 index 0000000..85e5114 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt @@ -0,0 +1,26 @@ +package com.itlab.domain.aiusecase + +import com.itlab.domain.repository.NotesRepository + +class ApplyTagsUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke( + noteId: String, + newTags: Set, + ) { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found") + + val updated = + note.copy( + tags = newTags, + updatedAt = + kotlinx.datetime.Clock.System + .now(), + ) + + repo.updateNote(updated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt b/domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt new file mode 100644 index 0000000..5c75d4d --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt @@ -0,0 +1,25 @@ +package com.itlab.domain.aiusecase + +import com.itlab.domain.ai.NoteAiService +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository + +class SuggestSummaryUseCase( + private val ai: NoteAiService, + private val repo: NotesRepository, +) { + private fun extractText(note: Note): String = + note.contentItems + .filterIsInstance() + .joinToString("\n") { it.text } + + suspend operator fun invoke(noteId: String): String { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found: $noteId") + + val text = extractText(note) + return ai.summarize(text) + } +} diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt b/domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt new file mode 100644 index 0000000..6de701a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt @@ -0,0 +1,34 @@ +package com.itlab.domain.aiusecase + +import com.itlab.domain.ai.NoteAiService +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository + +class SuggestTagsUseCase( + private val ai: NoteAiService, + private val repo: NotesRepository, +) { + private fun extractText(note: Note): String = + note.contentItems + .filterIsInstance() + .joinToString("\n") { it.text } + + private fun extractImages(note: Note): List = + note.contentItems + .filterIsInstance() + .mapNotNull { image -> + image.source.localPath ?: image.source.remoteUrl + } + + suspend operator fun invoke(noteId: String): Set { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found: $noteId") + + val text = extractText(note) + val imageUrls = extractImages(note) + + return ai.tagTXT(text) + ai.tagIMGs(imageUrls) + } +} diff --git a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt new file mode 100644 index 0000000..9e4f5ed --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt @@ -0,0 +1,34 @@ +package com.itlab.domain.cloud + +import kotlinx.datetime.Instant +import java.io.File + +interface CloudDataSource { + suspend fun listNoteMetadata(userId: String): Result> + + suspend fun downloadNote(key: String): Result + + suspend fun uploadNote( + key: String, + json: String, + ): Result + + suspend fun deleteNote(key: String): Result + + suspend fun uploadMedia( + key: String, + file: File, + ): Result + + suspend fun downloadMedia( + key: String, + destination: File, + ): Result + + suspend fun deleteMedia(key: String): Result +} + +data class CloudNoteMetadata( + val key: String, + val updatedAt: Instant, +) diff --git a/domain/src/main/java/com/itlab/domain/cloud/SyncManager.kt b/domain/src/main/java/com/itlab/domain/cloud/SyncManager.kt new file mode 100644 index 0000000..3da4c89 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/cloud/SyncManager.kt @@ -0,0 +1,25 @@ +package com.itlab.domain.cloud + +import kotlinx.coroutines.flow.StateFlow + +interface SyncManager { + val syncState: StateFlow + + suspend fun sync(userId: String) + + suspend fun pushChanges(userId: String) + + suspend fun pullUpdates(userId: String) +} + +sealed class SyncState { + object Idle : SyncState() + + object Syncing : SyncState() + + data class Error( + val message: String, + ) : SyncState() + + object Success : SyncState() +} diff --git a/domain/src/main/java/com/itlab/domain/model/Note.kt b/domain/src/main/java/com/itlab/domain/model/Note.kt index 9d21d4c..2418cda 100644 --- a/domain/src/main/java/com/itlab/domain/model/Note.kt +++ b/domain/src/main/java/com/itlab/domain/model/Note.kt @@ -1,7 +1,73 @@ package com.itlab.domain.model +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import kotlinx.serialization.Serializable +import java.util.Collections.emptySet +import java.util.UUID + data class Note( - val id: String = "", + val id: String = UUID.randomUUID().toString(), val title: String = "", - val content: String = "", + val folderId: String? = null, + val contentItems: List = emptyList(), + val createdAt: Instant = Clock.System.now(), + val updatedAt: Instant = Clock.System.now(), + val tags: Set = emptySet(), + val isFavorite: Boolean = false, + val summary: String? = null, + val syncStatus: SyncStatus = SyncStatus.PENDING, ) + +@Serializable +data class DataSource( + val localPath: String? = null, + val remoteUrl: String? = null, +) { + val displayPath: String? get() = localPath ?: remoteUrl +} + +@Serializable +sealed class ContentItem { + @Serializable + data class Text( + val text: String, + val format: TextFormat = TextFormat.PLAIN, + ) : ContentItem() + + @Serializable + data class Image( + val source: DataSource, + val mimeType: String, + val width: Int? = null, + val height: Int? = null, + ) : ContentItem() + + @Serializable + data class File( + val source: DataSource, + val mimeType: String, + val name: String, + val size: Long? = null, + ) : ContentItem() + + @Serializable + data class Link( + val url: String, + val title: String? = null, + ) : ContentItem() +} + +@Serializable +enum class TextFormat { + PLAIN, + MARKDOWN, + HTML, +} + +enum class SyncStatus { + SYNCED, + PENDING, + SYNCING, + ERROR, +} diff --git a/domain/src/main/java/com/itlab/domain/model/NoteFolder.kt b/domain/src/main/java/com/itlab/domain/model/NoteFolder.kt new file mode 100644 index 0000000..c95bdca --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/model/NoteFolder.kt @@ -0,0 +1,13 @@ +package com.itlab.domain.model + +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import java.util.UUID + +data class NoteFolder( + val id: String = UUID.randomUUID().toString(), + val name: String, + val createdAt: Instant = Clock.System.now(), + val updatedAt: Instant = Clock.System.now(), + val metadata: Map = emptyMap(), +) diff --git a/domain/src/main/java/com/itlab/domain/repository/NoteFolderRepository.kt b/domain/src/main/java/com/itlab/domain/repository/NoteFolderRepository.kt new file mode 100644 index 0000000..6bd5cd8 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/repository/NoteFolderRepository.kt @@ -0,0 +1,21 @@ +package com.itlab.domain.repository + +import com.itlab.domain.model.NoteFolder +import kotlinx.coroutines.flow.Flow + +interface NoteFolderRepository { + fun observeFolders(): Flow> + + suspend fun createFolder(folder: NoteFolder): String + + suspend fun renameFolder( + id: String, + name: String, + ) + + suspend fun deleteFolder(id: String) + + suspend fun getFolderById(id: String): NoteFolder? + + suspend fun updateFolder(folder: NoteFolder) +} diff --git a/domain/src/main/java/com/itlab/domain/repository/NotesRepository.kt b/domain/src/main/java/com/itlab/domain/repository/NotesRepository.kt index e31cf2e..ddcc682 100644 --- a/domain/src/main/java/com/itlab/domain/repository/NotesRepository.kt +++ b/domain/src/main/java/com/itlab/domain/repository/NotesRepository.kt @@ -1,3 +1,18 @@ package com.itlab.domain.repository -interface NotesRepository +import com.itlab.domain.model.Note +import kotlinx.coroutines.flow.Flow + +interface NotesRepository { + fun observeNotes(): Flow> + + fun observeNotesByFolder(folderId: String): Flow> + + suspend fun getNoteById(id: String): Note? + + suspend fun createNote(note: Note): String + + suspend fun updateNote(note: Note) + + suspend fun deleteNote(id: String) +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt new file mode 100644 index 0000000..b0d06dc --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt @@ -0,0 +1,15 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import kotlinx.datetime.Clock + +class CreateFolderUseCase( + private val repo: NoteFolderRepository, +) { + suspend operator fun invoke(folder: NoteFolder): String { + // discuss + val folder = folder.copy(createdAt = Clock.System.now()) + return repo.createFolder(folder) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt new file mode 100644 index 0000000..fdc390a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt @@ -0,0 +1,14 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock + +class CreateNoteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(note: Note): String { + val note = note.copy(createdAt = Clock.System.now()) + return repo.createNote(note) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt new file mode 100644 index 0000000..9dd0169 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt @@ -0,0 +1,11 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.repository.NoteFolderRepository + +class DeleteFolderUseCase( + private val repo: NoteFolderRepository, +) { + suspend operator fun invoke(id: String) { + repo.deleteFolder(id) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt new file mode 100644 index 0000000..65e8b8a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt @@ -0,0 +1,11 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.repository.NotesRepository + +class DeleteNoteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(noteId: String) { + repo.deleteNote(noteId) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt new file mode 100644 index 0000000..dbbd872 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt @@ -0,0 +1,10 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository + +class GetFolderUseCase( + private val repo: NoteFolderRepository, +) { + suspend operator fun invoke(id: String): NoteFolder? = repo.getFolderById(id) +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt new file mode 100644 index 0000000..bec0c5a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt @@ -0,0 +1,10 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository + +class GetNoteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(id: String): Note? = repo.getNoteById(id) +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt new file mode 100644 index 0000000..c5f0265 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt @@ -0,0 +1,17 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock + +class MoveNoteToFolderUseCase( + private val notesRepo: NotesRepository, +) { + suspend operator fun invoke( + folderId: String, + noteId: String, + ) { + val note = notesRepo.getNoteById(noteId) ?: throw IllegalArgumentException("Note not found: $noteId") + val updated = note.copy(folderId = folderId, updatedAt = Clock.System.now()) + notesRepo.updateNote(updated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt new file mode 100644 index 0000000..92b7a3a --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt @@ -0,0 +1,11 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import kotlinx.coroutines.flow.Flow + +class ObserveFoldersUseCase( + private val repo: NoteFolderRepository, +) { + operator fun invoke(): Flow> = repo.observeFolders() +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt new file mode 100644 index 0000000..3634333 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt @@ -0,0 +1,15 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class ObserveNotesByFolderUseCase( + private val repo: NotesRepository, +) { + operator fun invoke(folderId: String?): Flow> = + repo.observeNotes().map { notes -> + if (folderId == null) notes else notes.filter { it.folderId == folderId } + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt new file mode 100644 index 0000000..1fbfa3b --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt @@ -0,0 +1,11 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.coroutines.flow.Flow + +class ObserveNotesUseCase( + private val repo: NotesRepository, +) { + operator fun invoke(): Flow> = repo.observeNotes() +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt new file mode 100644 index 0000000..2539c82 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt @@ -0,0 +1,14 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import kotlinx.datetime.Clock + +class UpdateFolderUseCase( + private val repo: NoteFolderRepository, +) { + suspend operator fun invoke(folder: NoteFolder) { + val folder = folder.copy(updatedAt = Clock.System.now()) + repo.updateFolder(folder) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt new file mode 100644 index 0000000..f7470ee --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt @@ -0,0 +1,14 @@ +package com.itlab.domain.usecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock + +class UpdateNoteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(note: Note) { + val note = note.copy(updatedAt = Clock.System.now()) + repo.updateNote(note) + } +} diff --git a/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt new file mode 100644 index 0000000..97d4c3b --- /dev/null +++ b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt @@ -0,0 +1,246 @@ +package com.itlab.domain + +import com.itlab.domain.ai.NoteAiService +import com.itlab.domain.aiusecase.ApplySummaryUseCase +import com.itlab.domain.aiusecase.ApplyTagsUseCase +import com.itlab.domain.aiusecase.SuggestSummaryUseCase +import com.itlab.domain.aiusecase.SuggestTagsUseCase +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.DataSource +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.fail +import org.junit.Test + +class AIUseCasesTest { + private class FakeNotesRepo : NotesRepository { + private val store = mutableMapOf() + private val flow = MutableStateFlow>(emptyList()) + + override fun observeNotes(): Flow> = flow + + override fun observeNotesByFolder(folderId: String): Flow> = + flow.map { notes -> + notes.filter { it.folderId == folderId } + } + + override suspend fun getNoteById(id: String): Note? = store[id] + + override suspend fun createNote(note: Note): String { + store[note.id] = note + flow.value = store.values.toList() + return note.id + } + + override suspend fun updateNote(note: Note) { + store[note.id] = note + flow.value = store.values.toList() + } + + override suspend fun deleteNote(id: String) { + store.remove(id) + flow.value = store.values.toList() + } + } + + private class FakeNoteAiService : NoteAiService { + var summaryInput: String? = null + var textTagsInput: String? = null + var imageTagsInput: List = emptyList() + + var summaryResult: String = "AI summary" + var textTagsResult: Set = setOf("text-tag-1", "text-tag-2") + var imageTagsResult: Set = setOf("image-tag-1", "image-tag-2") + + override suspend fun summarize(text: String): String { + summaryInput = text + return summaryResult + } + + override suspend fun tagIMGs(img: List): Set { + imageTagsInput = img + return imageTagsResult + } + + override suspend fun tagTXT(text: String): Set { + textTagsInput = text + return textTagsResult + } + } + + @Test + fun suggestSummary_returnsDataAndSendsJoinedTextToAi() = + runBlocking { + val repo = FakeNotesRepo() + val ai = FakeNoteAiService() + val useCase = SuggestSummaryUseCase(ai, repo) + + val note = + Note( + id = "n1", + title = "Test", + contentItems = + listOf( + ContentItem.Text("Hello"), + ContentItem.Image( + source = DataSource(localPath = "path/to/img"), + mimeType = "image/png", + ), + ), + ) + repo.createNote(note) + + val result = useCase("n1") + + assertEquals("AI summary", result) + assertEquals("Hello", ai.summaryInput) + } + + @Test + fun suggestSummary_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val ai = FakeNoteAiService() + val useCase = SuggestSummaryUseCase(ai, repo) + + try { + useCase("missing_id") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found: missing_id", e.message) + } + } + + @Test + fun suggestTags_returnsMergedTags_andSendsTextAndImagesToAi() = + runBlocking { + val repo = FakeNotesRepo() + val ai = FakeNoteAiService() + val useCase = SuggestTagsUseCase(ai, repo) + + val note = + Note( + id = "n2", + title = "Tags", + contentItems = + listOf( + ContentItem.Text("First line"), + ContentItem.Text("Second line"), + ContentItem.Image( + source = DataSource(localPath = "/local/image.png"), + mimeType = "image/png", + ), + ContentItem.Image( + source = DataSource(remoteUrl = "https://example.com/image.jpg"), + mimeType = "image/jpg", + ), + ContentItem.Link("https://kotlinlang.org"), + ), + ) + repo.createNote(note) + + val result = useCase("n2") + + assertEquals("First line\nSecond line", ai.textTagsInput) + assertEquals( + listOf("/local/image.png", "https://example.com/image.jpg"), + ai.imageTagsInput, + ) + assertEquals( + setOf("text-tag-1", "text-tag-2", "image-tag-1", "image-tag-2"), + result, + ) + } + + @Test + fun suggestTags_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val ai = FakeNoteAiService() + val useCase = SuggestTagsUseCase(ai, repo) + + try { + useCase("missing_id") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found: missing_id", e.message) + } + } + + @Test + fun applySummary_updatesNoteSummary() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = ApplySummaryUseCase(repo) + + val note = + Note( + id = "n3", + title = "Summary", + summary = "old summary", + ) + repo.createNote(note) + + useCase("n3", "new summary") + + val updated = repo.getNoteById("n3") + + assertEquals("new summary", updated?.summary) + } + + @Test + fun applySummary_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = ApplySummaryUseCase(repo) + + try { + useCase("missing_id", "new summary") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found", e.message) + } + } + + @Test + fun applyTags_updatesNoteTags() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = ApplyTagsUseCase(repo) + + val note = + Note( + id = "n4", + title = "Tags", + tags = setOf("old"), + ) + repo.createNote(note) + + val newTags = setOf("kotlin", "android", "openvino") + + useCase("n4", newTags) + + val updated = repo.getNoteById("n4") + + assertEquals(newTags, updated?.tags) + } + + @Test + fun applyTags_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = ApplyTagsUseCase(repo) + + try { + useCase("missing_id", setOf("tag")) + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found", e.message) + } + } +} diff --git a/domain/src/test/java/com/itlab/domain/ExampleUnitTest.kt b/domain/src/test/java/com/itlab/domain/ExampleUnitTest.kt deleted file mode 100644 index 62dba3e..0000000 --- a/domain/src/test/java/com/itlab/domain/ExampleUnitTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.itlab.domain - -import com.itlab.domain.model.Note -import com.itlab.domain.repository.NotesRepository -import com.itlab.domain.usecase.AnalyzeNoteUseCase -import org.junit.Assert.assertEquals -import org.junit.Assert.assertNotNull -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun createsDomainComponents() { - val note = Note(id = "1", title = "Title", content = "Body") - val repository: NotesRepository = object : NotesRepository {} - val useCase = AnalyzeNoteUseCase() - - assertEquals("1", note.id) - assertNotNull(repository) - assertNotNull(useCase) - } -} diff --git a/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt new file mode 100644 index 0000000..fbe465b --- /dev/null +++ b/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt @@ -0,0 +1,122 @@ +package com.itlab.domain + +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import com.itlab.domain.usecase.CreateFolderUseCase +import com.itlab.domain.usecase.DeleteFolderUseCase +import com.itlab.domain.usecase.GetFolderUseCase +import com.itlab.domain.usecase.ObserveFoldersUseCase +import com.itlab.domain.usecase.UpdateFolderUseCase +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test + +class FolderUseCasesTest { + private class FakeFolderRepo : NoteFolderRepository { + private val store = mutableMapOf() + private val flow = MutableStateFlow>(emptyList()) + + override fun observeFolders() = flow + + override suspend fun createFolder(folder: NoteFolder): String { + store[folder.id] = folder + flow.value = store.values.toList() + return folder.id + } + + override suspend fun renameFolder( + id: String, + name: String, + ) { + val folder = store[id] ?: return + val updated = folder.copy(name = name) + store[id] = updated + flow.value = store.values.toList() + } + + override suspend fun deleteFolder(id: String) { + store.remove(id) + flow.value = store.values.toList() + } + + override suspend fun getFolderById(id: String): NoteFolder? = store[id] + + override suspend fun updateFolder(folder: NoteFolder) { + store[folder.id] = folder + flow.value = store.values.toList() + } + } + + @Test + fun createFolder_and_getFolder() = + runBlocking { + val repo = FakeFolderRepo() + + val create = CreateFolderUseCase(repo) + val get = GetFolderUseCase(repo) + + val folder = NoteFolder(id = "1", name = "Test") + + create(folder) + + val result = get("1") + + assertEquals("Test", result?.name) + } + + @Test + fun updateFolder_works() = + runBlocking { + val repo = FakeFolderRepo() + + val create = CreateFolderUseCase(repo) + val update = UpdateFolderUseCase(repo) + val get = GetFolderUseCase(repo) + + val folder = NoteFolder(id = "1", name = "Old") + create(folder) + + val updated = folder.copy(name = "New") + update(updated) + + val result = get("1") + + assertEquals("New", result?.name) + } + + @Test + fun deleteFolder_works() = + runBlocking { + val repo = FakeFolderRepo() + + val create = CreateFolderUseCase(repo) + val delete = DeleteFolderUseCase(repo) + val get = GetFolderUseCase(repo) + + val folder = NoteFolder(id = "1", name = "Test") + create(folder) + + delete("1") + + val result = get("1") + + assertNull(result) + } + + @Test + fun observeFolders_emitsData() = + runBlocking { + val repo = FakeFolderRepo() + val create = CreateFolderUseCase(repo) + val observe = ObserveFoldersUseCase(repo) + + create(NoteFolder(id = "1", name = "A")) + + val list = observe().first() + + assertEquals(1, list.size) + } +} diff --git a/domain/src/test/java/com/itlab/domain/NoteFolderTest.kt b/domain/src/test/java/com/itlab/domain/NoteFolderTest.kt new file mode 100644 index 0000000..84da2a4 --- /dev/null +++ b/domain/src/test/java/com/itlab/domain/NoteFolderTest.kt @@ -0,0 +1,24 @@ +package com.itlab.domain + +import com.itlab.domain.model.NoteFolder +import org.junit.Assert.assertEquals +import org.junit.Test + +class NoteFolderTest { + @Test + fun folder_creation() { + val folder = NoteFolder(id = "1", name = "Test") + + assertEquals("Test", folder.name) + } + + @Test + fun folder_copy() { + val folder = NoteFolder(id = "1", name = "Old") + + val updated = folder.copy(name = "New") + + assertEquals("Old", folder.name) + assertEquals("New", updated.name) + } +} diff --git a/domain/src/test/java/com/itlab/domain/NoteTest.kt b/domain/src/test/java/com/itlab/domain/NoteTest.kt new file mode 100644 index 0000000..5d9e5e5 --- /dev/null +++ b/domain/src/test/java/com/itlab/domain/NoteTest.kt @@ -0,0 +1,51 @@ +package com.itlab.domain + +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.DataSource +import com.itlab.domain.model.Note +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class NoteTest { + @Test + fun note_creation() { + val note = Note(title = "Hello") + + assertEquals("Hello", note.title) + assertTrue(note.contentItems.isEmpty()) + } + + @Test + fun note_copy() { + val note = Note(title = "A") + + val updated = note.copy(title = "B") + + assertEquals("A", note.title) + assertEquals("B", updated.title) + } + + @Test + fun content_items_types() { + val items = + listOf( + ContentItem.Text("text"), + ContentItem.Image( + source = DataSource(localPath = "/cache/images/pic_001.jpg"), + mimeType = "type", + ), + ContentItem.Link("url"), + ContentItem.File( + source = DataSource(remoteUrl = "https://url.com"), + mimeType = "type", + name = "name", + ), + ) + + assertTrue(items[0] is ContentItem.Text) + assertTrue(items[1] is ContentItem.Image) + assertTrue(items[2] is ContentItem.Link) + assertTrue(items[3] is ContentItem.File) + } +} diff --git a/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt new file mode 100644 index 0000000..be3d572 --- /dev/null +++ b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt @@ -0,0 +1,131 @@ +package com.itlab.domain + +import com.itlab.domain.model.Note +import com.itlab.domain.model.NoteFolder +import com.itlab.domain.repository.NoteFolderRepository +import com.itlab.domain.repository.NotesRepository +import com.itlab.domain.usecase.CreateNoteUseCase +import com.itlab.domain.usecase.DeleteNoteUseCase +import com.itlab.domain.usecase.GetNoteUseCase +import com.itlab.domain.usecase.MoveNoteToFolderUseCase +import com.itlab.domain.usecase.ObserveNotesUseCase +import com.itlab.domain.usecase.UpdateNoteUseCase +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Test + +class NoteUseCasesTest { + private class FakeNotesRepo : NotesRepository { + private val store = mutableMapOf() + private val flow = MutableStateFlow>(emptyList()) + + override fun observeNotes() = flow + + override fun observeNotesByFolder(folderId: String) = flow + + override suspend fun getNoteById(id: String): Note? = store[id] + + override suspend fun createNote(note: Note): String { + store[note.id] = note + flow.value = store.values.toList() + return note.id + } + + override suspend fun updateNote(note: Note) { + store[note.id] = note + flow.value = store.values.toList() + } + + override suspend fun deleteNote(id: String) { + store.remove(id) + flow.value = store.values.toList() + } + } + + private class FakeFolderRepo : NoteFolderRepository { + private val store = mutableMapOf() + + override fun observeFolders() = MutableStateFlow(emptyList()) + + override suspend fun createFolder(folder: NoteFolder): String { + store[folder.id] = folder + return folder.id + } + + override suspend fun renameFolder( + id: String, + name: String, + ) = Unit + + override suspend fun deleteFolder(id: String) = Unit + + override suspend fun getFolderById(id: String): NoteFolder? = store[id] + + override suspend fun updateFolder(folder: NoteFolder) = Unit + } + + @Test + fun create_update_delete_note() = + runBlocking { + val repo = FakeNotesRepo() + + val create = CreateNoteUseCase(repo) + val update = UpdateNoteUseCase(repo) + val delete = DeleteNoteUseCase(repo) + val get = GetNoteUseCase(repo) + + val note = Note(id = "n1", title = "A") + + create(note) + + val updated = note.copy(title = "B") + update(updated) + + val result = get("n1") + assertEquals("B", result?.title) + + delete("n1") + + val result2 = get("n1") + assertNull(result2) + } + + @Test + fun moveNoteToFolder_works() = + runBlocking { + val notesRepo = FakeNotesRepo() + val folderRepo = FakeFolderRepo() + + val move = MoveNoteToFolderUseCase(notesRepo) + val createNote = CreateNoteUseCase(notesRepo) + + val folder = NoteFolder(id = "f1", name = "Folder") + folderRepo.createFolder(folder) + + val note = Note(id = "n1", title = "Note") + createNote(note) + + move("f1", "n1") + + val updated = notesRepo.getNoteById("n1") + + assertEquals("f1", updated?.folderId) + } + + @Test + fun observeNotes_returnsData() = + runBlocking { + val repo = FakeNotesRepo() + val observe = ObserveNotesUseCase(repo) + val create = CreateNoteUseCase(repo) + + create(Note(id = "n1", title = "Test")) + + val list = observe().first() + + assertEquals(1, list.size) + } +} diff --git a/gradle.properties b/gradle.properties index 20e2a01..2892715 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,9 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +org.gradle.caching=true +# Local-friendly: disable Gradle dependency verification (can be re-enabled in CI) +org.gradle.dependency.verification=off # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. For more details, visit # https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects @@ -20,4 +23,5 @@ kotlin.code.style=official # Enables namespacing of each library's R class so that its R class includes only the # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true \ No newline at end of file +android.nonTransitiveRClass=true +android.suppressUnsupportedCompileSdk=37.0 diff --git a/gradle/gradle-daemon-jvm.properties b/gradle/gradle-daemon-jvm.properties new file mode 100644 index 0000000..ae79801 --- /dev/null +++ b/gradle/gradle-daemon-jvm.properties @@ -0,0 +1,12 @@ +#This file is generated by updateDaemonJvm +toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect +toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect +toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect +toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect +toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/dc463b4a8183dbcaa1b32544189c7f03/redirect +toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/cb7dc109dd590ebca2d703734d23c9d3/redirect +toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/65aaef917b9f394804f058f1861225c9/redirect +toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/c728c5388b044fbdbbc44b0c6acee0df/redirect +toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/43ee83889b87bacad5d3071ae7bbd349/redirect +toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/2d57bdd1e17a18f83ff073919daa35ba/redirect +toolchainVersion=17 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 67b8e6a..edd42bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,18 +1,26 @@ [versions] -agp = "8.13.2" -kotlin = "2.0.21" -coreKtx = "1.17.0" +agp = "9.1.0" +kotlin = "2.3.20" +coreKtx = "1.18.0" junit = "4.13.2" junitVersion = "1.3.0" espressoCore = "3.7.0" +kotlinxDatetime = "0.6.0" lifecycleRuntimeKtx = "2.10.0" -activityCompose = "1.12.4" -composeBom = "2024.09.00" -appcompat = "1.6.1" -material = "1.10.0" +activityCompose = "1.13.0" +appcompat = "1.7.1" +composeBom = "2026.03.00" +material = "1.13.0" detekt = "1.23.8" -kover = "0.9.1" -ktlintGradle = "12.3.0" +kover = "0.9.7" +ktlintGradle = "14.2.0" +room = "2.7.0" +ksp = "2.3.6" +timber = "5.0.1" +kotlinxSerializationJson = "1.6.3" +robolectric = "4.16.1" +coroutinesTest = "1.7.3" +coreTesting = "2.2.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -31,12 +39,26 @@ androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-te androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } +kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } +kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } +room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } +room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } +room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } +timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" } +androidx-compose-material-icons-core = { group = "androidx.compose.material", name = "material-icons-core" } +androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } +kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "coroutinesTest" } +mockk = { group = "io.mockk", name = "mockk", version = "1.13.10" } +robolectric = { group = "org.robolectric", name = "robolectric", version = "4.12.1" } +androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" } +androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } -kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } android-library = { id = "com.android.library", version.ref = "agp" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlintGradle" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } \ No newline at end of file diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 7fa2216..df6ab8c 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -12,6 +12,10 @@ + + + + @@ -139,6 +143,14 @@ + + + + + + + + @@ -160,6 +172,19 @@ + + + + + + + + + + + + + @@ -168,6 +193,19 @@ + + + + + + + + + + + + + @@ -234,6 +272,22 @@ + + + + + + + + + + + + + + + + @@ -242,6 +296,22 @@ + + + + + + + + + + + + + + + + @@ -271,6 +341,14 @@ + + + + + + + + @@ -305,6 +383,11 @@ + + + + + @@ -342,6 +425,19 @@ + + + + + + + + + + + + + @@ -355,6 +451,14 @@ + + + + + + + + @@ -371,6 +475,14 @@ + + + + + + + + @@ -384,6 +496,14 @@ + + + + + + + + @@ -400,6 +520,14 @@ + + + + + + + + @@ -413,6 +541,14 @@ + + + + + + + + @@ -429,6 +565,14 @@ + + + + + + + + @@ -442,6 +586,14 @@ + + + + + + + + @@ -458,11 +610,24 @@ + + + + + + + + + + + + + @@ -479,6 +644,11 @@ + + + + + @@ -487,6 +657,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -495,6 +723,14 @@ + + + + + + + + @@ -511,6 +747,14 @@ + + + + + + + + @@ -519,6 +763,22 @@ + + + + + + + + + + + + + + + + @@ -535,6 +795,14 @@ + + + + + + + + @@ -548,6 +816,14 @@ + + + + + + + + @@ -561,6 +837,14 @@ + + + + + + + + @@ -574,6 +858,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -590,6 +898,14 @@ + + + + + + + + @@ -608,6 +924,14 @@ + + + + + + + + @@ -621,6 +945,14 @@ + + + + + + + + @@ -634,6 +966,14 @@ + + + + + + + + @@ -647,6 +987,14 @@ + + + + + + + + @@ -655,6 +1003,14 @@ + + + + + + + + @@ -668,6 +1024,14 @@ + + + + + + + + @@ -681,6 +1045,14 @@ + + + + + + + + @@ -694,6 +1066,14 @@ + + + + + + + + @@ -707,6 +1087,14 @@ + + + + + + + + @@ -720,6 +1108,14 @@ + + + + + + + + @@ -733,6 +1129,14 @@ + + + + + + + + @@ -746,6 +1150,14 @@ + + + + + + + + @@ -759,6 +1171,14 @@ + + + + + + + + @@ -772,6 +1192,11 @@ + + + + + @@ -782,6 +1207,14 @@ + + + + + + + + @@ -795,6 +1228,11 @@ + + + + + @@ -805,6 +1243,14 @@ + + + + + + + + @@ -818,6 +1264,14 @@ + + + + + + + + @@ -831,6 +1285,14 @@ + + + + + + + + @@ -844,6 +1306,14 @@ + + + + + + + + @@ -857,6 +1327,14 @@ + + + + + + + + @@ -870,6 +1348,14 @@ + + + + + + + + @@ -883,6 +1369,14 @@ + + + + + + + + @@ -933,6 +1427,22 @@ + + + + + + + + + + + + + + + + @@ -957,6 +1467,19 @@ + + + + + + + + + + + + + @@ -965,6 +1488,14 @@ + + + + + + + + @@ -1005,6 +1536,14 @@ + + + + + + + + @@ -1013,6 +1552,14 @@ + + + + + + + + @@ -1042,6 +1589,14 @@ + + + + + + + + @@ -1051,6 +1606,9 @@ + + + @@ -1072,6 +1630,9 @@ + + + @@ -1084,6 +1645,11 @@ + + + + + @@ -1092,6 +1658,14 @@ + + + + + + + + @@ -1100,6 +1674,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -1145,6 +1740,19 @@ + + + + + + + + + + + + + @@ -1195,6 +1803,16 @@ + + + + + + + + + + @@ -1224,6 +1842,11 @@ + + + + + @@ -1250,6 +1873,11 @@ + + + + + @@ -1258,12 +1886,25 @@ - - - + + + - + + + + + + + + + + + + + + @@ -1275,6 +1916,22 @@ + + + + + + + + + + + + + + + + @@ -1415,6 +2072,11 @@ + + + + + @@ -1423,6 +2085,14 @@ + + + + + + + + @@ -1431,6 +2101,11 @@ + + + + + @@ -1439,6 +2114,14 @@ + + + + + + + + @@ -1463,6 +2146,14 @@ + + + + + + + + @@ -1484,6 +2175,14 @@ + + + + + + + + @@ -1492,6 +2191,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1505,6 +2288,24 @@ + + + + + + + + + + + + + + + + + + @@ -1526,6 +2327,14 @@ + + + + + + + + @@ -1534,6 +2343,11 @@ + + + + + @@ -1547,6 +2361,16 @@ + + + + + + + + + + @@ -1555,6 +2379,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1568,6 +2418,22 @@ + + + + + + + + + + + + + + + + @@ -1576,6 +2442,14 @@ + + + + + + + + @@ -1600,6 +2474,14 @@ + + + + + + + + @@ -1608,6 +2490,14 @@ + + + + + + + + @@ -1616,6 +2506,14 @@ + + + + + + + + @@ -1624,6 +2522,14 @@ + + + + + + + + @@ -1648,6 +2554,22 @@ + + + + + + + + + + + + + + + + @@ -1688,6 +2610,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1696,6 +2647,14 @@ + + + + + + + + @@ -1704,11 +2663,24 @@ + + + + + + + + + + + + + @@ -1717,6 +2689,14 @@ + + + + + + + + @@ -1725,11 +2705,24 @@ + + + + + + + + + + + + + @@ -1738,11 +2731,24 @@ + + + + + + + + + + + + + @@ -1751,6 +2757,14 @@ + + + + + + + + @@ -1759,6 +2773,14 @@ + + + + + + + + @@ -1767,6 +2789,14 @@ + + + + + + + + @@ -1775,6 +2805,14 @@ + + + + + + + + @@ -1783,6 +2821,14 @@ + + + + + + + + @@ -1791,6 +2837,14 @@ + + + + + + + + @@ -1799,6 +2853,14 @@ + + + + + + + + @@ -1807,6 +2869,14 @@ + + + + + + + + @@ -1815,6 +2885,14 @@ + + + + + + + + @@ -1823,6 +2901,14 @@ + + + + + + + + @@ -1831,6 +2917,14 @@ + + + + + + + + @@ -1838,10 +2932,27 @@ + + + + + + + + + + + + + + + + + @@ -1850,6 +2961,14 @@ + + + + + + + + @@ -1858,6 +2977,14 @@ + + + + + + + + @@ -1866,6 +2993,14 @@ + + + + + + + + @@ -1874,6 +3009,14 @@ + + + + + + + + @@ -1882,6 +3025,14 @@ + + + + + + + + @@ -1890,6 +3041,14 @@ + + + + + + + + @@ -1898,6 +3057,14 @@ + + + + + + + + @@ -1906,6 +3073,14 @@ + + + + + + + + @@ -1914,6 +3089,14 @@ + + + + + + + + @@ -1922,6 +3105,14 @@ + + + + + + + + @@ -1930,6 +3121,14 @@ + + + + + + + + @@ -1938,6 +3137,14 @@ + + + + + + + + @@ -1946,6 +3153,14 @@ + + + + + + + + @@ -1978,6 +3193,14 @@ + + + + + + + + @@ -1986,6 +3209,14 @@ + + + + + + + + @@ -1994,6 +3225,14 @@ + + + + + + + + @@ -2002,6 +3241,14 @@ + + + + + + + + @@ -2010,6 +3257,14 @@ + + + + + + + + @@ -2018,6 +3273,14 @@ + + + + + + + + @@ -2026,6 +3289,14 @@ + + + + + + + + @@ -2034,6 +3305,14 @@ + + + + + + + + @@ -2042,7 +3321,15 @@ - + + + + + + + + + @@ -2050,6 +3337,14 @@ + + + + + + + + @@ -2058,6 +3353,14 @@ + + + + + + + + @@ -2066,6 +3369,14 @@ + + + + + + + + @@ -2074,6 +3385,14 @@ + + + + + + + + @@ -2082,6 +3401,14 @@ + + + + + + + + @@ -2106,6 +3433,14 @@ + + + + + + + + @@ -2114,6 +3449,14 @@ + + + + + + + + @@ -2122,6 +3465,14 @@ + + + + + + + + @@ -2130,6 +3481,14 @@ + + + + + + + + @@ -2138,6 +3497,14 @@ + + + + + + + + @@ -2146,6 +3513,14 @@ + + + + + + + + @@ -2154,6 +3529,14 @@ + + + + + + + + @@ -2162,6 +3545,14 @@ + + + + + + + + @@ -2170,6 +3561,14 @@ + + + + + + + + @@ -2178,6 +3577,14 @@ + + + + + + + + @@ -2186,6 +3593,14 @@ + + + + + + + + @@ -2194,6 +3609,14 @@ + + + + + + + + @@ -2202,6 +3625,14 @@ + + + + + + + + @@ -2210,6 +3641,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -2218,6 +3673,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -2234,6 +3710,14 @@ + + + + + + + + @@ -2264,6 +3748,11 @@ + + + + + @@ -2285,6 +3774,22 @@ + + + + + + + + + + + + + + + + @@ -2293,11 +3798,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2345,6 +3878,14 @@ + + + + + + + + @@ -2369,6 +3910,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2382,6 +3997,11 @@ + + + + + @@ -2390,6 +4010,14 @@ + + + + + + + + @@ -2416,6 +4044,19 @@ + + + + + + + + + + + + + @@ -2426,11 +4067,26 @@ + + + + + + + + + + + + + + + @@ -2451,6 +4107,16 @@ + + + + + + + + + + @@ -2475,6 +4141,22 @@ + + + + + + + + + + + + + + + + @@ -2483,6 +4165,14 @@ + + + + + + + + @@ -2491,11 +4181,24 @@ + + + + + + + + + + + + + @@ -2506,6 +4209,11 @@ + + + + + @@ -2522,6 +4230,14 @@ + + + + + + + + @@ -2566,6 +4282,16 @@ + + + + + + + + + + @@ -2582,6 +4308,19 @@ + + + + + + + + + + + + + @@ -2606,6 +4345,14 @@ + + + + + + + + @@ -2614,6 +4361,14 @@ + + + + + + + + @@ -2629,6 +4384,16 @@ + + + + + + + + + + @@ -2637,6 +4402,14 @@ + + + + + + + + @@ -2645,6 +4418,14 @@ + + + + + + + + @@ -2653,6 +4434,14 @@ + + + + + + + + @@ -2661,6 +4450,14 @@ + + + + + + + + @@ -2669,6 +4466,14 @@ + + + + + + + + @@ -2677,6 +4482,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -2685,6 +4511,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2693,6 +4556,14 @@ + + + + + + + + @@ -2701,6 +4572,14 @@ + + + + + + + + @@ -2709,6 +4588,14 @@ + + + + + + + + @@ -2717,6 +4604,14 @@ + + + + + + + + @@ -2725,6 +4620,14 @@ + + + + + + + + @@ -2733,6 +4636,14 @@ + + + + + + + + @@ -2741,6 +4652,14 @@ + + + + + + + + @@ -2749,6 +4668,14 @@ + + + + + + + + @@ -2757,6 +4684,14 @@ + + + + + + + + @@ -2765,6 +4700,14 @@ + + + + + + + + @@ -2773,6 +4716,14 @@ + + + + + + + + @@ -2781,6 +4732,14 @@ + + + + + + + + @@ -2789,6 +4748,14 @@ + + + + + + + + @@ -2797,6 +4764,14 @@ + + + + + + + + @@ -2805,6 +4780,14 @@ + + + + + + + + @@ -2813,6 +4796,14 @@ + + + + + + + + @@ -2821,6 +4812,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -2902,6 +4914,22 @@ + + + + + + + + + + + + + + + + @@ -2936,6 +4964,11 @@ + + + + + @@ -2955,6 +4988,17 @@ + + + + + + + + + + + @@ -2993,6 +5037,9 @@ + + + @@ -3000,6 +5047,19 @@ + + + + + + + + + + + + + @@ -3016,6 +5076,17 @@ + + + + + + + + + + + @@ -3354,6 +5425,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3617,6 +5753,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -3706,6 +5863,11 @@ + + + + + @@ -3719,6 +5881,22 @@ + + + + + + + + + + + + + + + + @@ -3745,6 +5923,16 @@ + + + + + + + + + + @@ -3823,6 +6011,14 @@ + + + + + + + + @@ -3831,6 +6027,14 @@ + + + + + + + + @@ -3844,6 +6048,14 @@ + + + + + + + + @@ -3852,6 +6064,14 @@ + + + + + + + + @@ -3904,6 +6124,14 @@ + + + + + + + + @@ -3912,11 +6140,24 @@ + + + + + + + + + + + + + @@ -3956,6 +6197,19 @@ + + + + + + + + + + + + + @@ -3977,6 +6231,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4001,6 +6292,11 @@ + + + + + @@ -4041,6 +6337,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4049,6 +6369,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4070,6 +6414,14 @@ + + + + + + + + @@ -4078,6 +6430,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4086,6 +6462,14 @@ + + + + + + + + @@ -4102,6 +6486,22 @@ + + + + + + + + + + + + + + + + @@ -4110,6 +6510,14 @@ + + + + + + + + @@ -4118,6 +6526,14 @@ + + + + + + + + @@ -4126,6 +6542,14 @@ + + + + + + + + @@ -4142,6 +6566,22 @@ + + + + + + + + + + + + + + + + @@ -4150,6 +6590,19 @@ + + + + + + + + + + + + + @@ -4158,6 +6611,14 @@ + + + + + + + + @@ -4169,6 +6630,14 @@ + + + + + + + + @@ -4177,6 +6646,14 @@ + + + + + + + + @@ -4185,6 +6662,14 @@ + + + + + + + + @@ -4201,6 +6686,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4209,6 +6718,14 @@ + + + + + + + + @@ -4217,6 +6734,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4225,6 +6766,14 @@ + + + + + + + + @@ -4241,6 +6790,22 @@ + + + + + + + + + + + + + + + + @@ -4257,6 +6822,22 @@ + + + + + + + + + + + + + + + + @@ -4273,6 +6854,22 @@ + + + + + + + + + + + + + + + + @@ -4305,6 +6902,22 @@ + + + + + + + + + + + + + + + + @@ -4337,6 +6950,11 @@ + + + + + @@ -4348,14 +6966,67 @@ - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4390,16 +7061,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4424,6 +7120,11 @@ + + + + + @@ -4432,6 +7133,14 @@ + + + + + + + + @@ -4440,6 +7149,14 @@ + + + + + + + + @@ -4477,6 +7194,14 @@ + + + + + + + + @@ -4485,6 +7210,14 @@ + + + + + + + + @@ -4493,6 +7226,14 @@ + + + + + + + + @@ -4501,6 +7242,14 @@ + + + + + + + + @@ -4509,16 +7258,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4561,6 +7341,11 @@ + + + + + @@ -4587,6 +7372,11 @@ + + + + + @@ -4639,6 +7429,14 @@ + + + + + + + + @@ -4672,6 +7470,22 @@ + + + + + + + + + + + + + + + + @@ -4681,6 +7495,19 @@ + + + + + + + + + + + + + @@ -4689,6 +7516,11 @@ + + + + + @@ -4699,6 +7531,11 @@ + + + + + @@ -4715,6 +7552,14 @@ + + + + + + + + @@ -4728,6 +7573,16 @@ + + + + + + + + + + @@ -4736,6 +7591,22 @@ + + + + + + + + + + + + + + + + @@ -4744,6 +7615,14 @@ + + + + + + + + @@ -4752,6 +7631,14 @@ + + + + + + + + @@ -4760,11 +7647,24 @@ + + + + + + + + + + + + + @@ -4773,11 +7673,24 @@ + + + + + + + + + + + + + @@ -4802,6 +7715,19 @@ + + + + + + + + + + + + + @@ -4810,6 +7736,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4818,11 +7792,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4831,6 +7855,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4839,6 +7887,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -4847,6 +7916,22 @@ + + + + + + + + + + + + + + + + @@ -4855,6 +7940,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -4863,6 +7972,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4879,6 +8212,14 @@ + + + + + + + + @@ -4889,6 +8230,11 @@ + + + + + @@ -4897,6 +8243,11 @@ + + + + + @@ -4916,5 +8267,21 @@ + + + + + + + + + + + + + + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8bdaf60c75ab801e22807dde59e12a8735a34077..d997cfc60f4cff0e7451d19d49a82fa986695d07 100644 GIT binary patch delta 39724 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ⅆA{k6{Sa_dPB>TF4Im=mf;z@rf2j7Tr#P>Bp9qL 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 delta 36423 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c7a2c30..c385eaa 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,9 +1,7 @@ -#Mon Mar 09 18:04:29 MSK 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/gradlew b/gradlew index ef07e01..0262dcb 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index db3a6ac..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,94 +1,93 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH= - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts index b391eb4..c8c34a9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -11,6 +11,9 @@ pluginManagement { gradlePluginPortal() } } +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" +} dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { From f23d828abbd29e81d170ee249bc0fae31aefaf4a Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 15:59:24 +0200 Subject: [PATCH 02/25] fix: add dep --- data/src/main/java/com/itlab/data/dao/FolderDao.kt | 1 - domain/build.gradle.kts | 5 +++-- .../src/main/java/com/itlab/domain/cloud/CloudDataSource.kt | 5 +++++ domain/src/main/java/com/itlab/domain/model/Note.kt | 1 + gradle/libs.versions.toml | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/data/src/main/java/com/itlab/data/dao/FolderDao.kt b/data/src/main/java/com/itlab/data/dao/FolderDao.kt index f9e1e9d..543a442 100644 --- a/data/src/main/java/com/itlab/data/dao/FolderDao.kt +++ b/data/src/main/java/com/itlab/data/dao/FolderDao.kt @@ -8,7 +8,6 @@ import androidx.room.Query import androidx.room.Update import com.itlab.data.entity.FolderEntity import kotlinx.coroutines.flow.Flow - @Dao interface FolderDao { @Query("SELECT * FROM folders ORDER BY name ASC") diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index f9bed20..3e9769c 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -1,8 +1,8 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - alias(libs.plugins.android.library) - kotlin("plugin.serialization") + alias(libs.plugins.android.library) + alias(libs.plugins.kotlin.serialization) } android { @@ -40,6 +40,7 @@ kotlin { } dependencies { + api(libs.kotlinx.coroutines.core) implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) diff --git a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt index 9e4f5ed..bdb6d2d 100644 --- a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt +++ b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt @@ -3,6 +3,11 @@ package com.itlab.domain.cloud import kotlinx.datetime.Instant import java.io.File +sealed interface Result { + data class Success(val data: T) : Result + data class Error(val exception: Throwable) : Result +} + interface CloudDataSource { suspend fun listNoteMetadata(userId: String): Result> diff --git a/domain/src/main/java/com/itlab/domain/model/Note.kt b/domain/src/main/java/com/itlab/domain/model/Note.kt index 2418cda..972b802 100644 --- a/domain/src/main/java/com/itlab/domain/model/Note.kt +++ b/domain/src/main/java/com/itlab/domain/model/Note.kt @@ -3,6 +3,7 @@ package com.itlab.domain.model import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.Serializable +import java.util.Collections.emptyList import java.util.Collections.emptySet import java.util.UUID diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index edd42bd..54b510a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -52,6 +52,7 @@ mockk = { group = "io.mockk", name = "mockk", version = "1.13.10" } robolectric = { group = "org.robolectric", name = "robolectric", version = "4.12.1" } androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } +kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutinesTest" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 1266135043b00ee64d9b3a3d22886fbcbf1ce992 Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 18:33:36 +0200 Subject: [PATCH 03/25] feat: add files to work --- data/src/main/java/com/itlab/data/cloud/AuthManager.kt | 0 data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt | 0 .../src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt | 0 data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt | 0 data/src/main/java/com/itlab/data/cloud/SyncWorker.kt | 0 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/src/main/java/com/itlab/data/cloud/AuthManager.kt create mode 100644 data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt create mode 100644 data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt create mode 100644 data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt create mode 100644 data/src/main/java/com/itlab/data/cloud/SyncWorker.kt diff --git a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt new file mode 100644 index 0000000..e69de29 diff --git a/data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt b/data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt new file mode 100644 index 0000000..e69de29 diff --git a/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt b/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt new file mode 100644 index 0000000..e69de29 diff --git a/data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt b/data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt new file mode 100644 index 0000000..e69de29 diff --git a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt new file mode 100644 index 0000000..e69de29 From a8a7064eb1495522b01bf9563f1cf84a66809465 Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 18:39:38 +0200 Subject: [PATCH 04/25] feat: add new dep for await() --- data/build.gradle.kts | 1 + data/src/main/java/com/itlab/data/dao/FolderDao.kt | 1 + domain/build.gradle.kts | 2 +- .../main/java/com/itlab/domain/cloud/CloudDataSource.kt | 9 +++++++-- gradle/libs.versions.toml | 2 ++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/data/build.gradle.kts b/data/build.gradle.kts index d7aab12..d8c886d 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -46,6 +46,7 @@ dependencies { implementation(libs.material) implementation(libs.room.runtime) implementation(libs.room.ktx) + implementation(libs.kotlinx.coroutines.play.services) ksp(libs.room.compiler) implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) diff --git a/data/src/main/java/com/itlab/data/dao/FolderDao.kt b/data/src/main/java/com/itlab/data/dao/FolderDao.kt index 543a442..f9e1e9d 100644 --- a/data/src/main/java/com/itlab/data/dao/FolderDao.kt +++ b/data/src/main/java/com/itlab/data/dao/FolderDao.kt @@ -8,6 +8,7 @@ import androidx.room.Query import androidx.room.Update import com.itlab.data.entity.FolderEntity import kotlinx.coroutines.flow.Flow + @Dao interface FolderDao { @Query("SELECT * FROM folders ORDER BY name ASC") diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 3e9769c..e21acc5 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - alias(libs.plugins.android.library) + alias(libs.plugins.android.library) alias(libs.plugins.kotlin.serialization) } diff --git a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt index bdb6d2d..d84f86d 100644 --- a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt +++ b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt @@ -4,8 +4,13 @@ import kotlinx.datetime.Instant import java.io.File sealed interface Result { - data class Success(val data: T) : Result - data class Error(val exception: Throwable) : Result + data class Success( + val data: T, + ) : Result + + data class Error( + val exception: Throwable, + ) : Result } interface CloudDataSource { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 54b510a..e653017 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,6 +21,7 @@ kotlinxSerializationJson = "1.6.3" robolectric = "4.16.1" coroutinesTest = "1.7.3" coreTesting = "2.2.0" +kotlinxCoroutines = "1.7.3" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -53,6 +54,7 @@ robolectric = { group = "org.robolectric", name = "robolectric", version = "4.12 androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutinesTest" } +kotlinx-coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "kotlinxCoroutines" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 2db5dbf47d212c26f60145f9156070fd03ac51bc Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 18:44:05 +0200 Subject: [PATCH 05/25] fix: fix name --- .../data/cloud/{CloudDataSource.kt => CloudDataSourceImpl.kt} | 0 .../data/cloud/{NotesSyncManager.kt => NotesSyncManagerImpl.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename data/src/main/java/com/itlab/data/cloud/{CloudDataSource.kt => CloudDataSourceImpl.kt} (100%) rename data/src/main/java/com/itlab/data/cloud/{NotesSyncManager.kt => NotesSyncManagerImpl.kt} (100%) diff --git a/data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt b/data/src/main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt similarity index 100% rename from data/src/main/java/com/itlab/data/cloud/CloudDataSource.kt rename to data/src/main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt diff --git a/data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt b/data/src/main/java/com/itlab/data/cloud/NotesSyncManagerImpl.kt similarity index 100% rename from data/src/main/java/com/itlab/data/cloud/NotesSyncManager.kt rename to data/src/main/java/com/itlab/data/cloud/NotesSyncManagerImpl.kt From 800444d13d99ef592c00ed406d81a20f9898d00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:50:16 +0300 Subject: [PATCH 06/25] feat: add userId field --- app/build.gradle.kts | 3 + app/google-services.json | 29 ++ app/gradle.lockfile | 391 +++++++++++------- build.gradle.kts | 1 + .../main/java/com/itlab/data/dao/FolderDao.kt | 1 + .../java/com/itlab/data/entity/NoteEntity.kt | 1 + .../java/com/itlab/data/mapper/NoteMapper.kt | 2 + .../java/com/itlab/data/dao/MediaDaoTest.kt | 3 +- .../java/com/itlab/data/dao/NoteDaoTest.kt | 2 + .../com/itlab/data/entity/NoteEntityTest.kt | 11 + .../com/itlab/data/mapper/NoteMapperTest.kt | 8 + .../repository/NotesRepositoryImplTest.kt | 13 +- domain/build.gradle.kts | 2 +- .../com/itlab/domain/cloud/CloudDataSource.kt | 9 +- .../main/java/com/itlab/domain/model/Note.kt | 1 + .../java/com/itlab/domain/AIUseCasesTest.kt | 6 + .../test/java/com/itlab/domain/NoteTest.kt | 6 +- .../java/com/itlab/domain/NoteUseCasesTest.kt | 8 +- gradle/libs.versions.toml | 5 +- 19 files changed, 332 insertions(+), 170 deletions(-) create mode 100644 app/google-services.json diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1bbae64..c07f3f7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,6 +3,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.compose) + id("com.google.gms.google-services") } android { @@ -86,4 +87,6 @@ dependencies { debugImplementation(libs.androidx.compose.ui.test.manifest) implementation(libs.androidx.compose.material.icons.core) implementation(libs.androidx.compose.material.icons.extended) + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.analytics) } diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..3ec8b6d --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "267244224775", + "project_id": "openvino-notes", + "storage_bucket": "openvino-notes.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:267244224775:android:fb17f8492f57205ffec5a2", + "android_client_info": { + "package_name": "com.itlab.notes" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyDLAUPgzEm2R49WU4iGidAUj5b1jBb6FjQ" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/gradle.lockfile b/app/gradle.lockfile index 86a8e11..7701d6e 100644 --- a/app/gradle.lockfile +++ b/app/gradle.lockfile @@ -2,204 +2,265 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. androidx.activity:activity-compose:1.12.4=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.activity:activity-compose:1.13.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.activity:activity-compose:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.activity:activity-ktx:1.12.4=releaseUnitTestRuntimeClasspath -androidx.activity:activity-ktx:1.13.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.activity:activity-ktx:1.13.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.activity:activity:1.12.4=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.activity:activity:1.13.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.annotation:annotation-experimental:1.4.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation-jvm:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.annotation:annotation:1.9.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.activity:activity:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.annotation:annotation-experimental:1.4.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation-jvm:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.annotation:annotation:1.9.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.appcompat:appcompat-resources:1.6.1=releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat-resources:1.7.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat-resources:1.7.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.appcompat:appcompat:1.6.1=releaseUnitTestRuntimeClasspath -androidx.appcompat:appcompat:1.7.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.arch.core:core-common:2.2.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.arch.core:core-runtime:2.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.autofill:autofill:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.cardview:cardview:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-jvm:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection-ktx:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.collection:collection:1.5.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.appcompat:appcompat:1.7.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.arch.core:core-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.autofill:autofill:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.cardview:cardview:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-jvm:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection-ktx:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.collection:collection:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.compose.animation:animation-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.animation:animation-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-core-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation-core-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.animation:animation-core-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation-core:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation-core:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.animation:animation-core:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.animation:animation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.animation:animation:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.animation:animation:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.foundation:foundation-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-layout-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.foundation:foundation-layout-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation-layout:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation-layout:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.foundation:foundation-layout:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.foundation:foundation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.foundation:foundation:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.foundation:foundation:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.compose.material3:material3-android:1.3.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material3:material3-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material3:material3-android:1.4.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.material3:material3:1.3.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material3:material3:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.compose.material:material-android:1.10.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath +androidx.compose.material3:material3:1.4.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-android:1.10.5=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath androidx.compose.material:material-icons-core-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-icons-core-android:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -androidx.compose.material:material-icons-core-desktop:1.7.8=releaseLintChecksClasspath +androidx.compose.material:material-icons-core-android:1.7.8=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-core-desktop:1.7.8=debugLintChecksClasspath,releaseLintChecksClasspath androidx.compose.material:material-icons-core:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-icons-core:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.compose.material:material-icons-extended-android:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -androidx.compose.material:material-icons-extended-desktop:1.7.8=releaseLintChecksClasspath -androidx.compose.material:material-icons-extended:1.7.8=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.compose.material:material-ripple-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-core:1.7.8=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-extended-android:1.7.8=debugAndroidTestCompileClasspath,debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.compose.material:material-icons-extended-desktop:1.7.8=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.compose.material:material-icons-extended:1.7.8=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-ripple-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.material:material-ripple-android:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material-ripple:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material-ripple:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.material:material-ripple:1.7.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.material:material:1.10.5=debugRuntimeClasspath,debugUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.material:material:1.10.5=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath +androidx.compose.runtime:runtime-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-annotation-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-annotation-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime-annotation-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-annotation:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-annotation:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime-annotation:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-retain-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.compose.runtime:runtime-retain:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.compose.runtime:runtime-saveable-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-retain-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-retain:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-saveable-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime-saveable-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime-saveable:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime-saveable:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime-saveable:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.runtime:runtime:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.runtime:runtime:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.runtime:runtime:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-geometry-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-geometry-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-geometry-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-geometry:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-geometry:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-geometry:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-graphics-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-graphics-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-graphics-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-graphics:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-graphics:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-graphics:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-test-manifest:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-text-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-test-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.compose.ui:ui-test-junit4-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.compose.ui:ui-test-junit4:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.compose.ui:ui-test-manifest:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-test:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.compose.ui:ui-text-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-text-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-text:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-text:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-text:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-data-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-data:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-preview-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-tooling-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-data-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-data:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-tooling-preview-android:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-tooling-preview-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling-preview:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-tooling-preview:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-tooling-preview:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-tooling:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -androidx.compose.ui:ui-unit-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-tooling:1.10.5=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +androidx.compose.ui:ui-unit-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-unit-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-unit:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-unit:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-unit:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-util-android:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-util-android:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-util-android:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui-util:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui-util:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui-util:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose.ui:ui:1.10.5=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose.ui:ui:1.10.5=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.compose.ui:ui:1.9.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.compose:compose-bom:2024.09.00=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.compose:compose-bom:2026.03.00=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.concurrent:concurrent-futures:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout-core:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.compose:compose-bom:2026.03.00=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.concurrent:concurrent-futures-ktx:1.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.concurrent:concurrent-futures:1.2.0=debugAndroidTestCompileClasspath +androidx.constraintlayout:constraintlayout-core:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.constraintlayout:constraintlayout-solver:2.0.1=releaseUnitTestRuntimeClasspath androidx.constraintlayout:constraintlayout:2.0.1=releaseUnitTestRuntimeClasspath -androidx.constraintlayout:constraintlayout:2.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.constraintlayout:constraintlayout:2.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.coordinatorlayout:coordinatorlayout:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.core:core-ktx:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core-ktx:1.18.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.core:core-viewtree:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.core:core:1.18.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.cursoradapter:cursoradapter:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview-poolingcontainer:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.customview:customview:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=releaseUnitTestRuntimeClasspath -androidx.drawerlayout:drawerlayout:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.cursoradapter:cursoradapter:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview-poolingcontainer:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +androidx.customview:customview:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.datastore:datastore-android:1.1.7=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-android:1.1.7=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-core-okio-jvm:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-okio:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-preferences-android:1.1.7=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-core-android:1.1.7=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-core-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-preferences-core:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-external-protobuf:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-preferences-proto:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore:1.1.7=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.drawerlayout:drawerlayout:1.1.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestRuntimeClasspath -androidx.dynamicanimation:dynamicanimation:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.emoji2:emoji2-views-helper:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.emoji2:emoji2:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.emoji2:emoji2-views-helper:1.4.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.emoji2:emoji2:1.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath androidx.fragment:fragment:1.3.6=releaseUnitTestRuntimeClasspath -androidx.fragment:fragment:1.5.4=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.graphics:graphics-path:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.fragment:fragment:1.5.4=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-path:1.0.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.graphics:graphics-shapes-android:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.graphics:graphics-shapes-desktop:1.0.1=releaseLintChecksClasspath -androidx.graphics:graphics-shapes:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.interpolator:interpolator:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-java8:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-common:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata-core:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-livedata:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-process:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-compose-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-compose:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-ktx-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime-ktx:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-runtime:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.loader:loader:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-android:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.graphics:graphics-shapes:1.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.interpolator:interpolator:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common-java8:2.10.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-common:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core-ktx:2.10.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata-core:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-livedata:2.10.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-process:2.10.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-compose-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-compose:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-ktx-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime-ktx:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-runtime:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.navigationevent:navigationevent-android:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent-android:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-compose-android:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent-compose-android:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent-compose-android:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent-compose:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent-compose:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent-compose:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.navigationevent:navigationevent:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.navigationevent:navigationevent:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=releaseUnitTestRuntimeClasspath -androidx.profileinstaller:profileinstaller:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta11=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices:1.1.0-beta11=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.profileinstaller:profileinstaller:1.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestRuntimeClasspath -androidx.recyclerview:recyclerview:1.2.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.room:room-common-jvm:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.room:room-common:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.room:room-ktx:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.room:room-runtime-android:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.room:room-runtime:2.7.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.savedstate:savedstate-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-compose-android:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-compose:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate-ktx:1.4.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.savedstate:savedstate:1.4.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.sqlite:sqlite-android:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.sqlite:sqlite-framework-android:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.sqlite:sqlite-framework:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.sqlite:sqlite:2.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.tracing:tracing:1.2.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.recyclerview:recyclerview:1.2.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.resourceinspection:resourceinspection-annotation:1.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.room:room-common-jvm:2.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-common:2.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-ktx:2.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-runtime-android:2.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.room:room-runtime:2.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.savedstate:savedstate-android:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-compose-android:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-compose:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate-ktx:1.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.savedstate:savedstate:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.sqlite:sqlite-android:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework-android:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite-framework:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.sqlite:sqlite:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.ext:junit:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test.services:storage:1.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:core:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:monitor:1.8.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.test:runner:1.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +androidx.tracing:tracing:1.1.0=debugAndroidTestCompileClasspath +androidx.tracing:tracing:1.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.transition:transition:1.2.0=releaseUnitTestRuntimeClasspath -androidx.transition:transition:1.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.vectordrawable:vectordrawable-animated:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.vectordrawable:vectordrawable:1.1.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.versionedparcelable:versionedparcelable:1.1.1=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager2:viewpager2:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.viewpager:viewpager:1.0.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.window:window-core-android:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.window:window-core:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.window:window:1.5.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.transition:transition:1.6.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.vectordrawable:vectordrawable-animated:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.vectordrawable:vectordrawable:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager2:viewpager2:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.window:window-core-android:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.window:window-core:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.window:window:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath ch.qos.logback:logback-classic:1.3.14=ktlint ch.qos.logback:logback-core:1.3.14=ktlint com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.gms:play-services-ads-identifier:18.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-base:18.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-basement:18.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-api:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-base:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-impl:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk-api:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-stats:17.0.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-tasks:18.4.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.material:material:1.10.0=releaseUnitTestRuntimeClasspath -com.google.android.material:material:1.13.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:1.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.jakewharton.timber:timber:5.0.1=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.material:material:1.13.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.11.0=debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.errorprone:error_prone_annotations:2.15.0=releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.26.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath +com.google.firebase:firebase-analytics:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-annotations:17.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-bom:34.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-common:22.0.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-components:19.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations-interop:17.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations:19.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-measurement-connector:19.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.guava:guava:31.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.guava:listenablefuture:1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.jakewharton.timber:timber:5.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint com.pinterest.ktlint:ktlint-cli-reporter-core:1.5.0=ktlint @@ -215,6 +276,8 @@ com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +com.squareup.okio:okio-jvm:3.4.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.squareup.okio:okio:3.4.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath dev.drewhamilton.poko:poko-annotations-jvm:0.17.1=detekt dev.drewhamilton.poko:poko-annotations-jvm:0.18.0=ktlint,ktlintRuleset dev.drewhamilton.poko:poko-annotations:0.17.1=detekt @@ -247,12 +310,16 @@ io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt -junit:junit:4.13.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.checkerframework:checker-qual:3.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset -org.hamcrest:hamcrest-core:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath org.jcommander:jcommander:1.85=detekt org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset -org.jetbrains.kotlin:kotlin-bom:1.8.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-bom:1.8.22=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-build-tools-cri-impl:2.3.20=kotlinBuildToolsApiClasspath @@ -267,6 +334,7 @@ org.jetbrains.kotlin:kotlin-daemon-client:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClasspath org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath +org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset org.jetbrains.kotlin:kotlin-reflect:2.0.21=detekt org.jetbrains.kotlin:kotlin-script-runtime:2.0.21=detekt,kotlinCompilerClasspath @@ -274,35 +342,40 @@ org.jetbrains.kotlin:kotlin-script-runtime:2.1.0=ktlint,ktlintRuleset org.jetbrains.kotlin:kotlin-script-runtime:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-stdlib-common:2.0.21=detekt,releaseUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter -org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib:2.1.0=ktlint,ktlintReporter,ktlintRuleset -org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kotlinBuildToolsApiClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-tooling-core:2.3.20=kotlinBuildToolsApiClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-datetime:0.6.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-html-jvm:0.8.1=detekt -org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.4.1=detekt,ktlintReporter -org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-serialization-core:1.4.1=detekt,ktlintReporter -org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1=detekt,ktlintReporter -org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1=detekt,ktlintReporter -org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3=debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kover-jvm-agent:0.9.7=koverJvmAgent,koverJvmReporter org.jetbrains:annotations:13.0=detekt,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintReporter,ktlintRuleset -org.jetbrains:annotations:23.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.jspecify:jspecify:1.0.0=debugCompileClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jetbrains:annotations:23.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +org.jspecify:jspecify:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.slf4j:slf4j-api:2.0.7=ktlint org.snakeyaml:snakeyaml-engine:2.7=detekt empty=androidApis,debugAnnotationProcessorClasspath,debugReverseMetadataValues,debugUnitTestAnnotationProcessorClasspath,detektPlugins,kotlinCompilerPluginClasspath,koverExternalArtifacts,lintChecks,releaseAnnotationProcessorClasspath,releaseReverseMetadataValues,releaseUnitTestAnnotationProcessorClasspath diff --git a/build.gradle.kts b/build.gradle.kts index ba7114d..02923db 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,7 @@ plugins { alias(libs.plugins.detekt) alias(libs.plugins.kover) kotlin("plugin.serialization") version "2.3.20" apply false + id("com.google.gms.google-services") version "4.4.4" apply false } configure { diff --git a/data/src/main/java/com/itlab/data/dao/FolderDao.kt b/data/src/main/java/com/itlab/data/dao/FolderDao.kt index 543a442..f9e1e9d 100644 --- a/data/src/main/java/com/itlab/data/dao/FolderDao.kt +++ b/data/src/main/java/com/itlab/data/dao/FolderDao.kt @@ -8,6 +8,7 @@ import androidx.room.Query import androidx.room.Update import com.itlab.data.entity.FolderEntity import kotlinx.coroutines.flow.Flow + @Dao interface FolderDao { @Query("SELECT * FROM folders ORDER BY name ASC") diff --git a/data/src/main/java/com/itlab/data/entity/NoteEntity.kt b/data/src/main/java/com/itlab/data/entity/NoteEntity.kt index 198c96a..3679c9f 100644 --- a/data/src/main/java/com/itlab/data/entity/NoteEntity.kt +++ b/data/src/main/java/com/itlab/data/entity/NoteEntity.kt @@ -8,6 +8,7 @@ import kotlinx.datetime.Instant data class NoteEntity( @PrimaryKey val id: String, + val userId: String, val title: String, val content: String, val folderId: String? = null, diff --git a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt index 5033a15..204f004 100644 --- a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt +++ b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt @@ -28,6 +28,7 @@ class NoteMapper( val noteEntity = NoteEntity( id = noteId, + userId = note.userId, title = note.title, folderId = note.folderId, content = json.encodeToString(note.contentItems), @@ -61,6 +62,7 @@ class NoteMapper( return Note( id = entity.id, + userId = entity.userId, title = entity.title, contentItems = items, folderId = entity.folderId, diff --git a/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt b/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt index d88e3a6..94d45b5 100644 --- a/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt +++ b/data/src/test/java/com/itlab/data/dao/MediaDaoTest.kt @@ -23,7 +23,7 @@ class MediaDaoTest { private lateinit var database: AppDatabase private lateinit var mediaDao: MediaDao private lateinit var noteDao: NoteDao - + private val testUserId = "test_user_1" val testTime = Instant.parse("2026-03-24T12:00:00Z") private suspend fun insertParentNote(id: String) { @@ -35,6 +35,7 @@ class MediaDaoTest { createdAt = testTime, updatedAt = kotlinx.datetime.Instant.fromEpochMilliseconds(0), isSynced = true, + userId = testUserId, ) noteDao.insert(note) } diff --git a/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt b/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt index 5da39f6..bc0cfc9 100644 --- a/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt +++ b/data/src/test/java/com/itlab/data/dao/NoteDaoTest.kt @@ -24,6 +24,7 @@ class NoteDaoTest { private lateinit var database: AppDatabase private lateinit var noteDao: NoteDao + private val testUserId = "test_user_1" val testTime = Instant.parse("2026-03-24T12:00:00Z") private fun createNote( @@ -38,6 +39,7 @@ class NoteDaoTest { createdAt = testTime, updatedAt = updatedAt, isSynced = isSynced, + userId = testUserId, ) @Before diff --git a/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt b/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt index 22ca791..b88c058 100644 --- a/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt +++ b/data/src/test/java/com/itlab/data/entity/NoteEntityTest.kt @@ -15,6 +15,7 @@ class NoteEntityTest { val note = NoteEntity( id = "note_1", + userId = "user_1", title = "Test Title", content = "Test Content", createdAt = testTime, @@ -23,6 +24,7 @@ class NoteEntityTest { ) assertEquals("note_1", note.id) + assertEquals("user_1", note.userId) assertEquals("Test Title", note.title) assertEquals("Test Content", note.content) assertFalse(note.isSynced) @@ -37,6 +39,7 @@ class NoteEntityTest { val note = NoteEntity( id = "note_2", + userId = "user_2", title = "Title 2", content = "Content 2", createdAt = customTime, @@ -44,6 +47,7 @@ class NoteEntityTest { isSynced = true, ) + assertEquals("user_2", note.userId) assertEquals(customTime, note.createdAt) assertEquals(customTime, note.updatedAt) assertTrue(note.isSynced) @@ -54,12 +58,14 @@ class NoteEntityTest { val note = NoteEntity( id = "1", + userId = "user_1", title = "Title", content = "Content", createdAt = testTime, updatedAt = testTime, ) assertEquals("1", note.id) + assertEquals("user_1", note.userId) assertEquals("Title", note.title) assertEquals(false, note.isSynced) } @@ -67,6 +73,7 @@ class NoteEntityTest { @Test fun `note equality and hashcode`() { val id = "1" + val userId = "user_1" val title = "A" val content = "B" val timestamp = kotlinx.datetime.Instant.fromEpochMilliseconds(123456789L) @@ -74,6 +81,7 @@ class NoteEntityTest { val note1 = NoteEntity( id = id, + userId = userId, title = title, content = content, isSynced = false, @@ -83,6 +91,7 @@ class NoteEntityTest { val note2 = NoteEntity( id = id, + userId = userId, title = title, content = content, isSynced = false, @@ -99,6 +108,7 @@ class NoteEntityTest { val note = NoteEntity( "1", + "user_1", "Old", "Text", createdAt = testTime, @@ -107,6 +117,7 @@ class NoteEntityTest { val updated = note.copy(title = "New", isSynced = true) assertEquals("New", updated.title) + assertEquals("user_1", updated.userId) assertEquals(true, updated.isSynced) assertEquals("1", updated.id) } diff --git a/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt index e549755..a382ded 100644 --- a/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt +++ b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt @@ -15,12 +15,14 @@ import org.junit.Test class NoteMapperTest { private val mapper = NoteMapper() + private val testUserId = "test-user-id" val testTime = Instant.parse("2026-03-24T12:00:00Z") @Test fun `toEntities should map all content types and media correctly`() { val note = Note( + userId = testUserId, title = "Business", tags = setOf("money", "market"), contentItems = @@ -45,6 +47,7 @@ class NoteMapperTest { val (entity, media) = mapper.toEntities(note) assertEquals(note.id, entity.id) + assertEquals(testUserId, entity.userId) assertEquals("Business", entity.title) assertTrue(entity.isFavorite) assertFalse(entity.isSynced) @@ -83,6 +86,7 @@ class NoteMapperTest { val corruptedEntity = NoteEntity( id = "test-id", + userId = testUserId, title = "Broken Note", content = "!!not a json!!", tags = "{broken_tags}", @@ -94,6 +98,7 @@ class NoteMapperTest { assertTrue(result.contentItems.isEmpty()) assertTrue(result.tags.isEmpty()) + assertEquals(testUserId, result.userId) assertEquals("Broken Note", result.title) } @@ -122,6 +127,7 @@ class NoteMapperTest { val entity = NoteEntity( id = "uuid-123", + userId = testUserId, title = "Test Note", folderId = "fuid-100", content = json.encodeToString>(originalItems), @@ -134,6 +140,7 @@ class NoteMapperTest { val resultNote = mapper.toDomain(entity) assertEquals("uuid-123", resultNote.id) + assertEquals(testUserId, resultNote.userId) assertEquals("Test Note", resultNote.title) assertEquals("fuid-100", resultNote.folderId) assertTrue(resultNote.isFavorite) @@ -147,6 +154,7 @@ class NoteMapperTest { val entityWithNullTags = NoteEntity( id = "test-null-tags", + userId = testUserId, title = "Note with NULL tags", content = "[]", tags = null, diff --git a/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt b/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt index 2afec51..8db1b5c 100644 --- a/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt +++ b/data/src/test/java/com/itlab/data/repository/NotesRepositoryImplTest.kt @@ -30,12 +30,14 @@ class NotesRepositoryImplTest { private val mediaDao = mockk(relaxed = true) private val mapper = NoteMapper() private val repository = NotesRepositoryImpl(noteDao, mediaDao, mapper) + private val testUserId = "test_user_1" @Test fun `createNote inserts note and media if exists`() = runTest { val note = Note( + userId = testUserId, id = "note_1", title = "Test", contentItems = emptyList(), @@ -54,6 +56,7 @@ class NotesRepositoryImplTest { runTest { val note = Note( + userId = testUserId, id = "note_1", title = "Updated", createdAt = Clock.System.now(), @@ -113,6 +116,7 @@ class NotesRepositoryImplTest { val noteWithMedia = Note( + userId = testUserId, id = "note_123", title = "Note with Image", contentItems = listOf(imageItem), @@ -130,7 +134,13 @@ class NotesRepositoryImplTest { @Test fun `updateNote without media should only call update and delete`() = runTest { - val noteWithoutMedia = Note(id = "2", title = "No Media", contentItems = emptyList()) + val noteWithoutMedia = + Note( + userId = testUserId, + id = "2", + title = "No Media", + contentItems = emptyList(), + ) repository.updateNote(noteWithoutMedia) @@ -230,6 +240,7 @@ class NotesRepositoryImplTest { ) val noteWithMedia = Note( + userId = testUserId, id = "note_with_pic", title = "Vacation", contentItems = listOf(imageItem), diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 3e9769c..e21acc5 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { - alias(libs.plugins.android.library) + alias(libs.plugins.android.library) alias(libs.plugins.kotlin.serialization) } diff --git a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt index bdb6d2d..d84f86d 100644 --- a/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt +++ b/domain/src/main/java/com/itlab/domain/cloud/CloudDataSource.kt @@ -4,8 +4,13 @@ import kotlinx.datetime.Instant import java.io.File sealed interface Result { - data class Success(val data: T) : Result - data class Error(val exception: Throwable) : Result + data class Success( + val data: T, + ) : Result + + data class Error( + val exception: Throwable, + ) : Result } interface CloudDataSource { diff --git a/domain/src/main/java/com/itlab/domain/model/Note.kt b/domain/src/main/java/com/itlab/domain/model/Note.kt index 972b802..e3a0067 100644 --- a/domain/src/main/java/com/itlab/domain/model/Note.kt +++ b/domain/src/main/java/com/itlab/domain/model/Note.kt @@ -8,6 +8,7 @@ import java.util.Collections.emptySet import java.util.UUID data class Note( + val userId: String, val id: String = UUID.randomUUID().toString(), val title: String = "", val folderId: String? = null, diff --git a/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt index 97d4c3b..2d6fd1d 100644 --- a/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt +++ b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt @@ -18,6 +18,8 @@ import org.junit.Assert.fail import org.junit.Test class AIUseCasesTest { + private val testUserId = "test_user_1" + private class FakeNotesRepo : NotesRepository { private val store = mutableMapOf() private val flow = MutableStateFlow>(emptyList()) @@ -84,6 +86,7 @@ class AIUseCasesTest { Note( id = "n1", title = "Test", + userId = testUserId, contentItems = listOf( ContentItem.Text("Hello"), @@ -127,6 +130,7 @@ class AIUseCasesTest { Note( id = "n2", title = "Tags", + userId = testUserId, contentItems = listOf( ContentItem.Text("First line"), @@ -183,6 +187,7 @@ class AIUseCasesTest { id = "n3", title = "Summary", summary = "old summary", + userId = testUserId, ) repo.createNote(note) @@ -218,6 +223,7 @@ class AIUseCasesTest { id = "n4", title = "Tags", tags = setOf("old"), + userId = testUserId, ) repo.createNote(note) diff --git a/domain/src/test/java/com/itlab/domain/NoteTest.kt b/domain/src/test/java/com/itlab/domain/NoteTest.kt index 5d9e5e5..5542eda 100644 --- a/domain/src/test/java/com/itlab/domain/NoteTest.kt +++ b/domain/src/test/java/com/itlab/domain/NoteTest.kt @@ -8,9 +8,11 @@ import org.junit.Assert.assertTrue import org.junit.Test class NoteTest { + private val testUserId = "test_user_1" + @Test fun note_creation() { - val note = Note(title = "Hello") + val note = Note(title = "Hello", userId = testUserId) assertEquals("Hello", note.title) assertTrue(note.contentItems.isEmpty()) @@ -18,7 +20,7 @@ class NoteTest { @Test fun note_copy() { - val note = Note(title = "A") + val note = Note(title = "A", userId = testUserId) val updated = note.copy(title = "B") diff --git a/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt index be3d572..9563b23 100644 --- a/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt +++ b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt @@ -18,6 +18,8 @@ import org.junit.Assert.assertNull import org.junit.Test class NoteUseCasesTest { + private val testUserId = "test_user_1" + private class FakeNotesRepo : NotesRepository { private val store = mutableMapOf() private val flow = MutableStateFlow>(emptyList()) @@ -77,7 +79,7 @@ class NoteUseCasesTest { val delete = DeleteNoteUseCase(repo) val get = GetNoteUseCase(repo) - val note = Note(id = "n1", title = "A") + val note = Note(id = "n1", title = "A", userId = testUserId) create(note) @@ -105,7 +107,7 @@ class NoteUseCasesTest { val folder = NoteFolder(id = "f1", name = "Folder") folderRepo.createFolder(folder) - val note = Note(id = "n1", title = "Note") + val note = Note(id = "n1", title = "Note", userId = testUserId) createNote(note) move("f1", "n1") @@ -122,7 +124,7 @@ class NoteUseCasesTest { val observe = ObserveNotesUseCase(repo) val create = CreateNoteUseCase(repo) - create(Note(id = "n1", title = "Test")) + create(Note(id = "n1", title = "Test", userId = testUserId)) val list = observe().first() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 54b510a..63d8957 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] agp = "9.1.0" +firebaseBom = "34.12.0" kotlin = "2.3.20" coreKtx = "1.18.0" junit = "4.13.2" @@ -24,6 +25,8 @@ coreTesting = "2.2.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" } +firebase-bom = { module = "com.google.firebase:firebase-bom", name = "firebase-bom", version.ref = "firebaseBom" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } @@ -62,4 +65,4 @@ detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlintGradle" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } -ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } \ No newline at end of file +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } From 1ed6f4a3cf9e206ec2a7d4bbf6c62c6c731a1acf Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 19:23:57 +0200 Subject: [PATCH 07/25] fix: fix dep --- data/build.gradle.kts | 6 ++++++ data/src/main/java/com/itlab/data/cloud/AuthManager.kt | 6 ++++++ .../main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt | 0 gradle/libs.versions.toml | 4 ++++ 4 files changed, 16 insertions(+) delete mode 100644 data/src/main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt diff --git a/data/build.gradle.kts b/data/build.gradle.kts index d8c886d..7413743 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -47,10 +47,16 @@ dependencies { implementation(libs.room.runtime) implementation(libs.room.ktx) implementation(libs.kotlinx.coroutines.play.services) + implementation(libs.firebase.firestore) + implementation(libs.firebase.storage) + implementation(libs.firebase.auth) + implementation(libs.firebase.ui.auth) ksp(libs.room.compiler) implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) implementation(libs.timber) + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.analytics) testImplementation(libs.junit) testImplementation(libs.junit) testImplementation(libs.kotlinx.coroutines.test) diff --git a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt index e69de29..9cd097f 100644 --- a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt +++ b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt @@ -0,0 +1,6 @@ +package com.itlab.data.cloud + +import android.content.Context +import android.content.Intent +import com.firebase.ui.auth.AuthUI +import com.google.firebase.auth.FirebaseAuth diff --git a/data/src/main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt b/data/src/main/java/com/itlab/data/cloud/CloudDataSourceImpl.kt deleted file mode 100644 index e69de29..0000000 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e74be7a..b694c6b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -58,6 +58,10 @@ androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutinesTest" } kotlinx-coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "kotlinxCoroutines" } +firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore-ktx" } +firebase-storage = { group = "com.google.firebase", name = "firebase-storage-ktx" } +firebase-auth = { group = "com.google.firebase", name = "firebase-auth-ktx" } +firebase-ui-auth = { group = "com.firebaseui", name = "firebase-ui-auth", version = "8.0.2" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 378b18369bb02dc66bfc5e3475abae65c3ddca05 Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 19:46:34 +0200 Subject: [PATCH 08/25] feat: add data class AuthManager --- .../java/com/itlab/data/cloud/AuthManager.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt index 9cd097f..3d13e9f 100644 --- a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt +++ b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt @@ -4,3 +4,27 @@ import android.content.Context import android.content.Intent import com.firebase.ui.auth.AuthUI import com.google.firebase.auth.FirebaseAuth + +class AuthManager( + private val auth: FirebaseAuth +){ + fun getSignInIntent(): Intent { + return AuthUI.getInstance() + .createSignInIntentBuilder() + .setAvailableProviders( + listOf( + AuthUI.IdpConfig.EmailBuilder().build(), + AuthUI.IdpConfig.GoogleBuilder().build() + ) + ) + + .setIsSmartLockEnabled(false) + .build() + } + + fun getCurrentUserId(): String? = auth.currentUser?.uid + + fun signOut(context: Context){ + AuthUI.getInstance().signOut(context) + } +} From e4676b04138fd66f801fe9343d874f8a076024b9 Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 20:10:37 +0200 Subject: [PATCH 09/25] feat: add new dep --- data/build.gradle.kts | 1 + data/src/main/java/com/itlab/data/cloud/SyncWorker.kt | 8 ++++++++ gradle/libs.versions.toml | 6 ++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 7413743..c52dc21 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -51,6 +51,7 @@ dependencies { implementation(libs.firebase.storage) implementation(libs.firebase.auth) implementation(libs.firebase.ui.auth) + implementation(libs.androidx.work.runtime.ktx) ksp(libs.room.compiler) implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) diff --git a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt index e69de29..02ba8fb 100644 --- a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt +++ b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt @@ -0,0 +1,8 @@ +package com.itlab.data.cloud + +import android.content.Context +import android.util.Log +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import com.itlab.domain.cloud.SyncManager +import com.itlab.data.cloud.AuthManager diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b694c6b..6cad0b6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,6 +23,7 @@ robolectric = "4.16.1" coroutinesTest = "1.7.3" coreTesting = "2.2.0" kotlinxCoroutines = "1.7.3" +workManager = "2.9.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -58,10 +59,11 @@ androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutinesTest" } kotlinx-coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "kotlinxCoroutines" } -firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore-ktx" } -firebase-storage = { group = "com.google.firebase", name = "firebase-storage-ktx" } +firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore" } +firebase-storage = { group = "com.google.firebase", name = "firebase-storage" } firebase-auth = { group = "com.google.firebase", name = "firebase-auth-ktx" } firebase-ui-auth = { group = "com.firebaseui", name = "firebase-ui-auth", version = "8.0.2" } +androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "workManager" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 95cad5469c63d740db9e2302878568fb3396f567 Mon Sep 17 00:00:00 2001 From: sannarat Date: Thu, 16 Apr 2026 20:38:14 +0200 Subject: [PATCH 10/25] feat: add class SynkWorker --- .../java/com/itlab/data/cloud/SyncWorker.kt | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt index 02ba8fb..870ea07 100644 --- a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt +++ b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt @@ -1,8 +1,34 @@ package com.itlab.data.cloud import android.content.Context -import android.util.Log +import timber.log.Timber import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.itlab.domain.cloud.SyncManager import com.itlab.data.cloud.AuthManager + +class SyncWorker( + context: Context, + params: WorkerParameters, + private val syncManager: SyncManager, + private val authManager: AuthManager +) : CoroutineWorker(context, params) { + + override suspend fun doWork(): Result { + val userId = authManager.getCurrentUserId() ?: run { + Timber.e("Sync failed: User is not authorized") + return Result.failure() + } + return try { + Timber.d("Starting sync for user: $userId") + syncManager.sync(userId) + + Timber.d("Sync completed successfully") + Result.success() + }catch (e: Exception){ + Timber.e(e, "Sync error occurred: %s", e.message) + + if (e is java.io.IOException) Result.retry() else Result.failure() + } + } +} From 572a0ceffbad79764ce426f30fd94943d358153a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Thu, 16 Apr 2026 22:59:01 +0300 Subject: [PATCH 11/25] feat: implement FirebaseCloudDataSource class --- data/build.gradle.kts | 2 +- .../java/com/itlab/data/cloud/AuthManager.kt | 6 -- .../data/cloud/FirebaseCloudDataSource.kt | 101 ++++++++++++++++++ .../itlab/data/cloud/NotesSyncManagerImpl.kt | 0 .../java/com/itlab/data/cloud/SyncWorker.kt | 0 gradle/libs.versions.toml | 8 +- 6 files changed, 106 insertions(+), 11 deletions(-) delete mode 100644 data/src/main/java/com/itlab/data/cloud/AuthManager.kt delete mode 100644 data/src/main/java/com/itlab/data/cloud/NotesSyncManagerImpl.kt delete mode 100644 data/src/main/java/com/itlab/data/cloud/SyncWorker.kt diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 7413743..819f388 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -40,6 +40,7 @@ kotlin { } dependencies { + implementation(platform(libs.firebase.bom)) implementation(project(":domain")) implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) @@ -55,7 +56,6 @@ dependencies { implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) implementation(libs.timber) - implementation(platform(libs.firebase.bom)) implementation(libs.firebase.analytics) testImplementation(libs.junit) testImplementation(libs.junit) diff --git a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt deleted file mode 100644 index 9cd097f..0000000 --- a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.itlab.data.cloud - -import android.content.Context -import android.content.Intent -import com.firebase.ui.auth.AuthUI -import com.google.firebase.auth.FirebaseAuth diff --git a/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt b/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt index e69de29..3b609e7 100644 --- a/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt +++ b/data/src/main/java/com/itlab/data/cloud/FirebaseCloudDataSource.kt @@ -0,0 +1,101 @@ +package com.itlab.data.cloud + +import com.google.firebase.storage.FirebaseStorage +import com.itlab.domain.cloud.CloudDataSource +import com.itlab.domain.cloud.CloudNoteMetadata +import com.itlab.domain.cloud.Result +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.tasks.await +import kotlinx.datetime.Instant +import java.io.File + +class FirebaseCloudDataSource( + private val storage: FirebaseStorage = FirebaseStorage.getInstance(), +) : CloudDataSource { + private val rootRef = storage.reference + + override suspend fun listNoteMetadata(userId: String): Result> = + safeCall { + val listRef = rootRef.child("users/$userId/notes") + val result = listRef.listAll().await() + + val metadataList = + result.items.map { itemRef -> + val metadata = itemRef.metadata.await() + CloudNoteMetadata( + key = itemRef.path, + updatedAt = Instant.fromEpochMilliseconds(metadata.updatedTimeMillis), + ) + } + metadataList + } + + override suspend fun downloadNote(key: String): Result = + safeCall { + val fileRef = rootRef.child(key) + val bytes = fileRef.getBytes(MAX_NOTE_SIZE).await() + String(bytes) + } + + override suspend fun uploadNote( + key: String, + json: String, + ): Result = + safeCall { + val fileRef = rootRef.child(key) + fileRef.putBytes(json.toByteArray()).await() + Unit + } + + override suspend fun deleteNote(key: String): Result = + safeCall { + rootRef.child(key).delete().await() + Unit + } + + override suspend fun uploadMedia( + key: String, + file: File, + ): Result = + safeCall { + val fileRef = rootRef.child(key) + file.inputStream().use { stream -> + fileRef.putStream(stream).await() + } + Unit + } + + override suspend fun downloadMedia( + key: String, + destination: File, + ): Result = + safeCall { + val fileRef = rootRef.child(key) + fileRef.getFile(destination).await() + Unit + } + + override suspend fun deleteMedia(key: String): Result = + safeCall { + rootRef.child(key).delete().await() + Unit + } + + @Suppress("TooGenericExceptionCaught") + private suspend inline fun safeCall(crossinline block: suspend () -> T): Result = + try { + Result.Success(block()) + } catch (e: CancellationException) { + throw e + } catch (e: com.google.firebase.FirebaseException) { + Result.Error(e) + } catch (e: java.io.IOException) { + Result.Error(e) + } catch (e: Exception) { + Result.Error(e) + } + + companion object { + private const val MAX_NOTE_SIZE = 5 * 1024 * 1024L // 5MB + } +} diff --git a/data/src/main/java/com/itlab/data/cloud/NotesSyncManagerImpl.kt b/data/src/main/java/com/itlab/data/cloud/NotesSyncManagerImpl.kt deleted file mode 100644 index e69de29..0000000 diff --git a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt deleted file mode 100644 index e69de29..0000000 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b694c6b..937c51e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ kotlinxCoroutines = "1.7.3" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" } -firebase-bom = { module = "com.google.firebase:firebase-bom", name = "firebase-bom", version.ref = "firebaseBom" } +firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } @@ -58,9 +58,9 @@ androidx-test-core = { group = "androidx.test", name = "core", version = "1.5.0" androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version = "1.1.5" } kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutinesTest" } kotlinx-coroutines-play-services = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-play-services", version.ref = "kotlinxCoroutines" } -firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore-ktx" } -firebase-storage = { group = "com.google.firebase", name = "firebase-storage-ktx" } -firebase-auth = { group = "com.google.firebase", name = "firebase-auth-ktx" } +firebase-firestore = { group = "com.google.firebase", name = "firebase-firestore" } +firebase-storage = { group = "com.google.firebase", name = "firebase-storage" } +firebase-auth = { group = "com.google.firebase", name = "firebase-auth" } firebase-ui-auth = { group = "com.firebaseui", name = "firebase-ui-auth", version = "8.0.2" } [plugins] From cabcc8aa0895d561e45c4de47cbfc96386d498f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:02:09 +0300 Subject: [PATCH 12/25] fix: fix build errors and detekt issues in cloud data source --- data/build.gradle.kts | 5 + data/gradle.lockfile | 124 +++++++++++++++--- data/lint-baseline.xml | 18 +++ .../java/com/itlab/data/cloud/AuthManager.kt | 20 ++- .../java/com/itlab/data/cloud/SyncWorker.kt | 30 +++-- 5 files changed, 159 insertions(+), 38 deletions(-) create mode 100644 data/lint-baseline.xml diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 627225d..986a028 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -31,6 +31,11 @@ android { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } + + lint { + baseline = file("lint-baseline.xml") + abortOnError = true + } } kotlin { diff --git a/data/gradle.lockfile b/data/gradle.lockfile index 324353b..588d709 100644 --- a/data/gradle.lockfile +++ b/data/gradle.lockfile @@ -14,6 +14,8 @@ androidx.appcompat:appcompat:1.7.1=debugAndroidTestCompileClasspath,debugAndroid androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.arch.core:core-runtime:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath androidx.arch.core:core-runtime:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.browser:browser:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection-jvm:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -30,9 +32,27 @@ androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestR androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.credentials:credentials-play-services-auth:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.credentials:credentials:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.customview:customview:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.datastore:datastore-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-jvm:1.1.7=debugLintChecksClasspath +androidx.datastore:datastore-core-okio-jvm:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-okio:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-jvm:1.1.7=debugLintChecksClasspath +androidx.datastore:datastore-preferences-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-core-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-core-jvm:1.1.7=debugLintChecksClasspath +androidx.datastore:datastore-preferences-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-external-protobuf:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-jvm:1.1.7=debugLintChecksClasspath +androidx.datastore:datastore-preferences-proto:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.datastore:datastore:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.drawerlayout:drawerlayout:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -46,17 +66,24 @@ androidx.graphics:graphics-shapes-android:1.0.1=debugAndroidTestCompileClasspath androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath androidx.graphics:graphics-shapes:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-v4:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-common:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-extensions:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-livedata:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-process:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-runtime:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-service:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.print:print:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.media:media:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath androidx.profileinstaller:profileinstaller:1.3.0=releaseUnitTestRuntimeClasspath androidx.profileinstaller:profileinstaller:1.3.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -73,11 +100,13 @@ androidx.room:room-migration:2.7.0=_agp_internal_debug_kspClasspath,_agp_interna androidx.room:room-runtime-android:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.room:room-runtime:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.savedstate:savedstate:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.startup:startup-runtime:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath androidx.test.espresso:espresso-idling-resource:3.5.1=debugUnitTestRuntimeClasspath androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath @@ -101,31 +130,78 @@ androidx.vectordrawable:vectordrawable:1.1.0=debugAndroidTestCompileClasspath,de androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.viewpager2:viewpager2:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.work:work-runtime-ktx:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.work:work-runtime:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath ch.qos.logback:logback-classic:1.3.14=ktlint ch.qos.logback:logback-core:1.3.14=ktlint com.almworks.sqlite4java:sqlite4java:1.0.392=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.firebaseui:firebase-ui-auth:8.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint com.github.ajalt.clikt:clikt:5.0.2=ktlint +com.google.android.gms:play-services-ads-identifier:18.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-api-phone:18.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-base:18.0.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth:20.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.android.gms:play-services-auth:20.7.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-base:18.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.android.gms:play-services-base:18.9.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-basement:18.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-fido:20.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-base:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-impl:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-stats:17.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-tasks:18.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.libraries.identity.googleid:googleid:1.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.google.android.material:material:1.10.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath com.google.android.material:material:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.play:core-common:2.0.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.play:integrity:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.recaptcha:recaptcha:18.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android:annotations:4.1.1.4=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.google.auto.value:auto-value-annotations:1.10.4=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath com.google.auto.value:auto-value-annotations:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.auto:auto-common:1.2.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.code.findbugs:jsr305:3.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +com.google.code.findbugs:jsr305:3.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.code.gson:gson:2.10.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.google.devtools.ksp:symbol-processing-api:2.0.10-1.0.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.devtools.ksp:symbol-processing:2.3.6=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease com.google.errorprone:error_prone_annotation:2.19.1=debugUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.11.0=debugUnitTestCompileClasspath -com.google.errorprone:error_prone_annotations:2.15.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.11.0=debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.errorprone:error_prone_annotations:2.15.0=releaseLintChecksClasspath,releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.26.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.google.errorprone:error_prone_annotations:2.26.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath -com.google.guava:failureaccess:1.0.1=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.firebase:firebase-analytics:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-annotations:17.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck-interop:17.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck:19.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth-interop:20.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth:24.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-bom:34.12.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-common:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-components:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-database-collection:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-firestore:26.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations-interop:17.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations:19.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-measurement-connector:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-storage:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:protolite-well-known-types:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath com.google.guava:failureaccess:1.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.guava:guava:31.1-jre=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.guava:guava:31.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,releaseCompileClasspath +com.google.guava:guava:31.1-jre=debugUnitTestCompileClasspath +com.google.guava:guava:32.1.3-android=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.google.guava:guava:33.2.1-jre=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.guava:listenablefuture:1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.j2objc:j2objc-annotations:1.3=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +com.google.guava:listenablefuture:1.0=releaseLintChecksClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.protobuf:protobuf-javalite:3.25.5=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.re2j:re2j:1.6=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.ibm.icu:icu4j:74.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath com.intellij:annotations:12.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.jakewharton.timber:timber:5.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -144,6 +220,8 @@ com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset +com.squareup.okio:okio-jvm:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.squareup.okio:okio:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath com.squareup:javapoet:1.13.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.squareup:kotlinpoet-javapoet:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.squareup:kotlinpoet-jvm:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath @@ -181,6 +259,14 @@ io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt +io.grpc:grpc-android:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-api:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-context:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-core:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-okhttp:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-protobuf-lite:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-stub:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-util:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath io.mockk:mockk-agent-api-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-agent-api:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-agent-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath @@ -191,20 +277,24 @@ io.mockk:mockk-dsl-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntim io.mockk:mockk-dsl:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +io.perfmark:perfmark-api:0.26.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath javax.annotation:javax.annotation-api:1.3.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath net.bytebuddy:byte-buddy:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.bouncycastle:bcprov-jdk18on:1.77=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -org.checkerframework:checker-qual:3.12.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath +org.checkerframework:checker-qual:3.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +org.checkerframework:checker-qual:3.37.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath org.checkerframework:checker-qual:3.42.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.23=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath org.conscrypt:conscrypt-openjdk-uber:2.5.2=debugUnitTestRuntimeClasspath org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath org.jcommander:jcommander:1.85=detekt org.jetbrains.intellij.deps:trove4j:1.0.20200330=detekt,kotlinCompilerClasspath,ktlint,ktlintRuleset +org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-bom:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-build-tools-compat:2.3.20=kotlinBuildToolsApiClasspath @@ -219,6 +309,7 @@ org.jetbrains.kotlin:kotlin-daemon-embeddable:2.0.21=detekt,kotlinCompilerClassp org.jetbrains.kotlin:kotlin-daemon-embeddable:2.1.0=ktlint,ktlintRuleset org.jetbrains.kotlin:kotlin-daemon-embeddable:2.3.20=kotlinBuildToolsApiClasspath org.jetbrains.kotlin:kotlin-metadata-jvm:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath +org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-reflect:1.6.10=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,ktlint,ktlintRuleset org.jetbrains.kotlin:kotlin-reflect:1.9.10=debugUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-reflect:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath @@ -232,9 +323,11 @@ org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter org.jetbrains.kotlin:kotlin-stdlib-common:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -252,6 +345,7 @@ org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=releaseUnitTestCompileCl org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath diff --git a/data/lint-baseline.xml b/data/lint-baseline.xml new file mode 100644 index 0000000..bc36162 --- /dev/null +++ b/data/lint-baseline.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt index 3d13e9f..50f5c0b 100644 --- a/data/src/main/java/com/itlab/data/cloud/AuthManager.kt +++ b/data/src/main/java/com/itlab/data/cloud/AuthManager.kt @@ -6,25 +6,23 @@ import com.firebase.ui.auth.AuthUI import com.google.firebase.auth.FirebaseAuth class AuthManager( - private val auth: FirebaseAuth -){ - fun getSignInIntent(): Intent { - return AuthUI.getInstance() + private val auth: FirebaseAuth, +) { + fun getSignInIntent(): Intent = + AuthUI + .getInstance() .createSignInIntentBuilder() .setAvailableProviders( listOf( AuthUI.IdpConfig.EmailBuilder().build(), - AuthUI.IdpConfig.GoogleBuilder().build() - ) - ) - - .setIsSmartLockEnabled(false) + AuthUI.IdpConfig.GoogleBuilder().build(), + ), + ).setIsSmartLockEnabled(false) .build() - } fun getCurrentUserId(): String? = auth.currentUser?.uid - fun signOut(context: Context){ + fun signOut(context: Context) { AuthUI.getInstance().signOut(context) } } diff --git a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt index 870ea07..d43f06a 100644 --- a/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt +++ b/data/src/main/java/com/itlab/data/cloud/SyncWorker.kt @@ -1,34 +1,40 @@ package com.itlab.data.cloud import android.content.Context -import timber.log.Timber import androidx.work.CoroutineWorker import androidx.work.WorkerParameters -import com.itlab.domain.cloud.SyncManager import com.itlab.data.cloud.AuthManager +import com.itlab.domain.cloud.SyncManager +import kotlinx.coroutines.CancellationException +import timber.log.Timber class SyncWorker( context: Context, params: WorkerParameters, private val syncManager: SyncManager, - private val authManager: AuthManager + private val authManager: AuthManager, ) : CoroutineWorker(context, params) { - + @Suppress("TooGenericExceptionCaught") override suspend fun doWork(): Result { - val userId = authManager.getCurrentUserId() ?: run { - Timber.e("Sync failed: User is not authorized") - return Result.failure() - } + val userId = + authManager.getCurrentUserId() ?: run { + Timber.e("Sync failed: User is not authorized") + return Result.failure() + } return try { Timber.d("Starting sync for user: $userId") syncManager.sync(userId) Timber.d("Sync completed successfully") Result.success() - }catch (e: Exception){ - Timber.e(e, "Sync error occurred: %s", e.message) - - if (e is java.io.IOException) Result.retry() else Result.failure() + } catch (e: CancellationException) { + throw e + } catch (e: java.io.IOException) { + Timber.e(e, "Sync retryable error: %s", e.message) + Result.retry() + } catch (e: Exception) { + Timber.e(e, "Sync fatal error: %s", e.message) + Result.failure() } } } From 2597c431337710308d082b3c8b1d9caf2ef326d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:42:07 +0300 Subject: [PATCH 13/25] refactor: narrow lint suppression for gRPC in data and app modules --- app/build.gradle.kts | 5 ++ app/gradle.lockfile | 55 +++++++++++- app/lint.xml | 6 ++ data/build.gradle.kts | 2 +- data/gradle.lockfile | 190 ++++++++++++++++++++--------------------- data/lint-baseline.xml | 18 ---- data/lint.xml | 6 ++ 7 files changed, 164 insertions(+), 118 deletions(-) create mode 100644 app/lint.xml delete mode 100644 data/lint-baseline.xml create mode 100644 data/lint.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c07f3f7..bbf180c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -58,6 +58,11 @@ android { } } } + + lint { + lintConfig = file("lint.xml") + abortOnError = true + } } kotlin { diff --git a/app/gradle.lockfile b/app/gradle.lockfile index 7701d6e..aa6b957 100644 --- a/app/gradle.lockfile +++ b/app/gradle.lockfile @@ -16,7 +16,9 @@ androidx.appcompat:appcompat:1.6.1=releaseUnitTestRuntimeClasspath androidx.appcompat:appcompat:1.7.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.arch.core:core-runtime:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.autofill:autofill:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.browser:browser:1.4.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.cardview:cardview:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection-jvm:1.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection-ktx:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath @@ -121,6 +123,8 @@ androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestR androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.credentials:credentials-play-services-auth:1.2.0-rc01=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.credentials:credentials:1.2.0-rc01=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.cursoradapter:cursoradapter:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.customview:customview-poolingcontainer:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.customview:customview:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath @@ -155,10 +159,13 @@ androidx.graphics:graphics-shapes-android:1.0.1=debugRuntimeClasspath,debugUnitT androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath androidx.graphics:graphics-shapes:1.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.interpolator:interpolator:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-core-ui:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-v4:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-common-java8:2.10.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-common-jvm:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-common:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-extensions:2.2.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-livedata-core-ktx:2.10.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-livedata-core:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-livedata:2.10.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath @@ -169,6 +176,7 @@ androidx.lifecycle:lifecycle-runtime-compose:2.10.0=debugAndroidTestCompileClass androidx.lifecycle:lifecycle-runtime-ktx-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-runtime-ktx:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-runtime:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.lifecycle:lifecycle-service:2.10.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel-savedstate-android:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -176,6 +184,7 @@ androidx.lifecycle:lifecycle-viewmodel-savedstate:2.10.0=debugAndroidTestCompile androidx.lifecycle:lifecycle-viewmodel:2.10.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.media:media:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent-android:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.navigationevent:navigationevent-android:1.0.2=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.navigationevent:navigationevent-compose-android:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -201,11 +210,13 @@ androidx.savedstate:savedstate-compose-android:1.4.0=debugAndroidTestCompileClas androidx.savedstate:savedstate-compose:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.savedstate:savedstate-ktx:1.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.savedstate:savedstate:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-android:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework-android:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite:2.5.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.startup:startup-runtime:1.1.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath +androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath androidx.test.ext:junit:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath @@ -225,13 +236,21 @@ androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugCompile androidx.window:window-core-android:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.window:window-core:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.window:window:1.5.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.work:work-runtime-ktx:2.9.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.work:work-runtime:2.9.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath ch.qos.logback:logback-classic:1.3.14=ktlint ch.qos.logback:logback-core:1.3.14=ktlint +com.firebaseui:firebase-ui-auth:8.0.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint com.github.ajalt.clikt:clikt:5.0.2=ktlint com.google.android.gms:play-services-ads-identifier:18.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-base:18.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-api-phone:18.0.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-base:18.0.4=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth:20.7.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-base:18.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.android.gms:play-services-base:18.9.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-basement:18.9.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-fido:20.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-measurement-api:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-measurement-base:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-measurement-impl:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -240,26 +259,43 @@ com.google.android.gms:play-services-measurement-sdk:23.2.0=debugAndroidTestComp com.google.android.gms:play-services-measurement:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-stats:17.0.2=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-tasks:18.4.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.libraries.identity.googleid:googleid:1.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.material:material:1.10.0=releaseUnitTestRuntimeClasspath com.google.android.material:material:1.13.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.play:core-common:2.0.3=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.play:integrity:1.3.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.recaptcha:recaptcha:18.6.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android:annotations:4.1.1.4=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.code.findbugs:jsr305:3.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.code.gson:gson:2.10.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.errorprone:error_prone_annotations:2.11.0=debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath com.google.errorprone:error_prone_annotations:2.15.0=releaseUnitTestRuntimeClasspath com.google.errorprone:error_prone_annotations:2.26.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath com.google.firebase:firebase-analytics:23.2.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-annotations:17.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck-interop:17.1.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck:19.0.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth-interop:20.0.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth:24.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-bom:34.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-common:22.0.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-components:19.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-database-collection:18.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-firestore:26.2.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-installations-interop:17.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-installations:19.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.firebase:firebase-measurement-connector:19.0.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-storage:22.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:protolite-well-known-types:18.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -com.google.guava:guava:31.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.guava:guava:31.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.guava:guava:32.1.3-android=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.guava:listenablefuture:1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +com.google.protobuf:protobuf-javalite:3.25.5=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.re2j:re2j:1.6=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.jakewharton.timber:timber:5.0.1=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.pinterest.ktlint:ktlint-cli-reporter-baseline:1.5.0=ktlint com.pinterest.ktlint:ktlint-cli-reporter-checkstyle:1.5.0=ktlint @@ -310,9 +346,20 @@ io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt +io.grpc:grpc-android:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-api:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-context:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-core:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-okhttp:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-protobuf-lite:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-stub:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-util:1.62.2=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.perfmark:perfmark-api:0.26.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -org.checkerframework:checker-qual:3.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.checkerframework:checker-qual:3.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath +org.checkerframework:checker-qual:3.37.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.23=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.hamcrest:hamcrest-library:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath diff --git a/app/lint.xml b/app/lint.xml new file mode 100644 index 0000000..1146fe8 --- /dev/null +++ b/app/lint.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 986a028..7a0819e 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -33,7 +33,7 @@ android { } lint { - baseline = file("lint-baseline.xml") + lintConfig = file("lint.xml") abortOnError = true } } diff --git a/data/gradle.lockfile b/data/gradle.lockfile index 588d709..e6fc498 100644 --- a/data/gradle.lockfile +++ b/data/gradle.lockfile @@ -14,8 +14,8 @@ androidx.appcompat:appcompat:1.7.1=debugAndroidTestCompileClasspath,debugAndroid androidx.arch.core:core-common:2.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.arch.core:core-runtime:2.1.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath androidx.arch.core:core-runtime:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.browser:browser:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.asynclayoutinflater:asynclayoutinflater:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.browser:browser:1.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.cardview:cardview:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection-jvm:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.collection:collection:1.4.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -32,27 +32,27 @@ androidx.core:core-ktx:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestR androidx.core:core-viewtree:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.17.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.core:core:1.18.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -androidx.credentials:credentials-play-services-auth:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -androidx.credentials:credentials:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.credentials:credentials-play-services-auth:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.credentials:credentials:1.2.0-rc01=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.cursoradapter:cursoradapter:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.customview:customview:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.datastore:datastore-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.datastore:datastore-core-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-core-jvm:1.1.7=debugLintChecksClasspath -androidx.datastore:datastore-core-okio-jvm:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-core-okio:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-jvm:1.1.7=debugLintChecksClasspath +androidx.datastore:datastore-core-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-core-okio-jvm:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core-okio:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath androidx.datastore:datastore-preferences-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath androidx.datastore:datastore-preferences-core-android:1.1.7=debugAndroidTestRuntimeClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-preferences-core-jvm:1.1.7=debugLintChecksClasspath -androidx.datastore:datastore-preferences-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-preferences-external-protobuf:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-preferences-jvm:1.1.7=debugLintChecksClasspath -androidx.datastore:datastore-preferences-proto:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore-preferences:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.datastore:datastore:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.datastore:datastore-preferences-core-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-preferences-core:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-external-protobuf:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences-jvm:1.1.7=debugLintChecksClasspath,releaseLintChecksClasspath +androidx.datastore:datastore-preferences-proto:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore-preferences:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.datastore:datastore:1.1.7=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.documentfile:documentfile:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.drawerlayout:drawerlayout:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.dynamicanimation:dynamicanimation:1.0.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.dynamicanimation:dynamicanimation:1.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -66,24 +66,24 @@ androidx.graphics:graphics-shapes-android:1.0.1=debugAndroidTestCompileClasspath androidx.graphics:graphics-shapes-desktop:1.0.1=debugLintChecksClasspath,releaseLintChecksClasspath androidx.graphics:graphics-shapes:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.interpolator:interpolator:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.legacy:legacy-support-v4:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.legacy:legacy-support-core-ui:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.legacy:legacy-support-core-utils:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.legacy:legacy-support-v4:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-common:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-extensions:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.lifecycle:lifecycle-extensions:2.2.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-livedata-core:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-livedata:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-process:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-runtime:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.lifecycle:lifecycle-service:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.lifecycle:lifecycle-service:2.6.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.lifecycle:lifecycle-viewmodel:2.6.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.loader:loader:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.media:media:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -androidx.privacysandbox.ads:ads-adservices:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.localbroadcastmanager:localbroadcastmanager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.media:media:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.print:print:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices-java:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.privacysandbox.ads:ads-adservices:1.1.0-beta11=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.profileinstaller:profileinstaller:1.3.0=releaseUnitTestRuntimeClasspath androidx.profileinstaller:profileinstaller:1.3.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.recyclerview:recyclerview:1.1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -100,13 +100,13 @@ androidx.room:room-migration:2.7.0=_agp_internal_debug_kspClasspath,_agp_interna androidx.room:room-runtime-android:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.room:room-runtime:2.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.savedstate:savedstate:1.2.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.slidingpanelayout:slidingpanelayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework-android:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite-framework:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.sqlite:sqlite:2.5.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.startup:startup-runtime:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestRuntimeClasspath -androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +androidx.swiperefreshlayout:swiperefreshlayout:1.0.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath androidx.test.espresso:espresso-core:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath androidx.test.espresso:espresso-idling-resource:3.5.1=debugUnitTestRuntimeClasspath androidx.test.espresso:espresso-idling-resource:3.7.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath @@ -130,78 +130,78 @@ androidx.vectordrawable:vectordrawable:1.1.0=debugAndroidTestCompileClasspath,de androidx.versionedparcelable:versionedparcelable:1.1.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.viewpager2:viewpager2:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath androidx.viewpager:viewpager:1.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -androidx.work:work-runtime-ktx:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -androidx.work:work-runtime:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +androidx.work:work-runtime-ktx:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +androidx.work:work-runtime:2.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath ch.qos.logback:logback-classic:1.3.14=ktlint ch.qos.logback:logback-core:1.3.14=ktlint com.almworks.sqlite4java:sqlite4java:1.0.392=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -com.firebaseui:firebase-ui-auth:8.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.firebaseui:firebase-ui-auth:8.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.github.ajalt.clikt:clikt-jvm:5.0.2=ktlint com.github.ajalt.clikt:clikt:5.0.2=ktlint -com.google.android.gms:play-services-ads-identifier:18.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-auth-api-phone:18.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-auth-base:18.0.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-ads-identifier:18.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-api-phone:18.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth-base:18.0.4=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-auth:20.3.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath -com.google.android.gms:play-services-auth:20.7.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-auth:20.7.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.gms:play-services-base:18.5.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath -com.google.android.gms:play-services-base:18.9.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-basement:18.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-fido:20.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement-base:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement-impl:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement-sdk-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement-sdk:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-measurement:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-stats:17.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.gms:play-services-tasks:18.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.libraries.identity.googleid:googleid:1.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-base:18.9.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-basement:18.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-fido:20.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-base:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-impl:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk-api:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement-sdk:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-measurement:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-stats:17.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.gms:play-services-tasks:18.4.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.libraries.identity.googleid:googleid:1.1.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.android.material:material:1.10.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath com.google.android.material:material:1.13.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -com.google.android.play:core-common:2.0.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.play:integrity:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android.recaptcha:recaptcha:18.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.android:annotations:4.1.1.4=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.android.play:core-common:2.0.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.play:integrity:1.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android.recaptcha:recaptcha:18.6.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.android:annotations:4.1.1.4=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.auto.value:auto-value-annotations:1.10.4=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath com.google.auto.value:auto-value-annotations:1.6.3=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.auto:auto-common:1.2.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.code.findbugs:jsr305:3.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.code.gson:gson:2.10.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.code.findbugs:jsr305:3.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.code.gson:gson:2.10.1=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.devtools.ksp:symbol-processing-api:2.0.10-1.0.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.devtools.ksp:symbol-processing:2.3.6=kotlinCompilerPluginClasspathDebug,kotlinCompilerPluginClasspathDebugUnitTest,kotlinCompilerPluginClasspathRelease com.google.errorprone:error_prone_annotation:2.19.1=debugUnitTestRuntimeClasspath com.google.errorprone:error_prone_annotations:2.11.0=debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath -com.google.errorprone:error_prone_annotations:2.15.0=releaseLintChecksClasspath,releaseUnitTestRuntimeClasspath -com.google.errorprone:error_prone_annotations:2.26.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.15.0=releaseUnitTestRuntimeClasspath +com.google.errorprone:error_prone_annotations:2.26.0=debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.errorprone:error_prone_annotations:2.26.1=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.errorprone:error_prone_annotations:2.30.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath -com.google.firebase:firebase-analytics:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-annotations:17.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-appcheck-interop:17.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-appcheck:19.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-auth-interop:20.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-auth:24.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-bom:34.12.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-common:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-components:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-database-collection:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-firestore:26.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-installations-interop:17.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-installations:19.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-measurement-connector:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:firebase-storage:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.firebase:protolite-well-known-types:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath -com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-analytics:23.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-annotations:17.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck-interop:17.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-appcheck:19.0.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth-interop:20.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-auth:24.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-bom:34.12.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-common:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-components:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-database-collection:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-firestore:26.2.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations-interop:17.3.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-installations:19.1.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-measurement-connector:19.0.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:firebase-storage:22.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.firebase:protolite-well-known-types:18.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.guava:failureaccess:1.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.guava:failureaccess:1.0.2=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.google.guava:guava:31.1-android=debugAndroidTestCompileClasspath,debugCompileClasspath,releaseCompileClasspath com.google.guava:guava:31.1-jre=debugUnitTestCompileClasspath -com.google.guava:guava:32.1.3-android=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.guava:guava:32.1.3-android=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.guava:guava:33.2.1-jre=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -com.google.guava:listenablefuture:1.0=releaseLintChecksClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath -com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseRuntimeClasspath +com.google.guava:listenablefuture:1.0=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.google.j2objc:j2objc-annotations:1.3=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath -com.google.protobuf:protobuf-javalite:3.25.5=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -com.google.re2j:re2j:1.6=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.google.protobuf:protobuf-javalite:3.25.5=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.google.re2j:re2j:1.6=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.ibm.icu:icu4j:74.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath com.intellij:annotations:12.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.jakewharton.timber:timber:5.0.1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath @@ -220,8 +220,8 @@ com.pinterest.ktlint:ktlint-logger:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine-core:1.5.0=ktlint,ktlintRuleset com.pinterest.ktlint:ktlint-rule-engine:1.5.0=ktlint com.pinterest.ktlint:ktlint-ruleset-standard:1.5.0=ktlint,ktlintRuleset -com.squareup.okio:okio-jvm:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -com.squareup.okio:okio:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +com.squareup.okio:okio-jvm:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +com.squareup.okio:okio:3.4.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath com.squareup:javapoet:1.13.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.squareup:kotlinpoet-javapoet:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath com.squareup:kotlinpoet-jvm:1.17.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath @@ -259,14 +259,14 @@ io.gitlab.arturbosch.detekt:detekt-rules-style:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-rules:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-tooling:1.23.8=detekt io.gitlab.arturbosch.detekt:detekt-utils:1.23.8=detekt -io.grpc:grpc-android:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-api:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-context:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-core:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-okhttp:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-protobuf-lite:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-stub:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath -io.grpc:grpc-util:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.grpc:grpc-android:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-api:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-context:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-core:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-okhttp:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-protobuf-lite:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-stub:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath +io.grpc:grpc-util:1.62.2=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath io.mockk:mockk-agent-api-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-agent-api:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-agent-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath @@ -277,17 +277,17 @@ io.mockk:mockk-dsl-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntim io.mockk:mockk-dsl:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk-jvm:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath io.mockk:mockk:1.13.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -io.perfmark:perfmark-api:0.26.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +io.perfmark:perfmark-api:0.26.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath javax.annotation:javax.annotation-api:1.3.2=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath -javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +javax.inject:javax.inject:1=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath junit:junit:4.13.2=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath net.bytebuddy:byte-buddy-agent:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath net.bytebuddy:byte-buddy:1.14.6=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.bouncycastle:bcprov-jdk18on:1.77=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.checkerframework:checker-qual:3.12.0=debugAndroidTestCompileClasspath,debugCompileClasspath,debugUnitTestCompileClasspath,releaseCompileClasspath -org.checkerframework:checker-qual:3.37.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +org.checkerframework:checker-qual:3.37.0=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.checkerframework:checker-qual:3.42.0=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath -org.codehaus.mojo:animal-sniffer-annotations:1.23=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseRuntimeClasspath +org.codehaus.mojo:animal-sniffer-annotations:1.23=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.conscrypt:conscrypt-openjdk-uber:2.5.2=debugUnitTestRuntimeClasspath org.ec4j.core:ec4j-core:1.1.0=ktlint,ktlintRuleset org.hamcrest:hamcrest-core:1.3=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -323,11 +323,11 @@ org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0=ktlintReporter org.jetbrains.kotlin:kotlin-stdlib-common:2.1.10=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib-common:2.3.20=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0=detekt,ktlintReporter -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0=detekt,ktlintReporter -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseRuntimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22=debugAndroidTestRuntimeClasspath,debugLintChecksClasspath,debugRuntimeClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24=_agp_internal_debug_kspClasspath,_agp_internal_release_kspClasspath,kspDebugKotlinProcessorClasspath,kspDebugUnitTestKotlinProcessorClasspath,kspReleaseKotlinProcessorClasspath org.jetbrains.kotlin:kotlin-stdlib:2.0.21=detekt,kotlinCompilerClasspath,releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath @@ -345,7 +345,7 @@ org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1=releaseUnitTestCompileCl org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1=releaseUnitTestCompileClasspath,releaseUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath -org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseRuntimeClasspath +org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0=debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.0=debugAndroidTestCompileClasspath,debugAndroidTestRuntimeClasspath,debugCompileClasspath,debugLintChecksClasspath,debugRuntimeClasspath,debugUnitTestCompileClasspath,debugUnitTestRuntimeClasspath,releaseCompileClasspath,releaseLintChecksClasspath,releaseRuntimeClasspath diff --git a/data/lint-baseline.xml b/data/lint-baseline.xml deleted file mode 100644 index bc36162..0000000 --- a/data/lint-baseline.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/data/lint.xml b/data/lint.xml new file mode 100644 index 0000000..1146fe8 --- /dev/null +++ b/data/lint.xml @@ -0,0 +1,6 @@ + + + + + + From bc0c972847adceeb0e0869d8e54b73717644eba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:43:44 +0300 Subject: [PATCH 14/25] feat: implement NoteDto data class --- .../data/mapper/NoteEntityJsonConverter.kt | 4 +++ .../main/java/com/itlab/data/model/NoteDto.kt | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt create mode 100644 data/src/main/java/com/itlab/data/model/NoteDto.kt diff --git a/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt b/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt new file mode 100644 index 0000000..7bb836d --- /dev/null +++ b/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt @@ -0,0 +1,4 @@ +package com.itlab.data.mapper + +class NoteEntityJsonConverter { +} diff --git a/data/src/main/java/com/itlab/data/model/NoteDto.kt b/data/src/main/java/com/itlab/data/model/NoteDto.kt new file mode 100644 index 0000000..91b4bc7 --- /dev/null +++ b/data/src/main/java/com/itlab/data/model/NoteDto.kt @@ -0,0 +1,26 @@ +package com.itlab.data.model + +import kotlinx.serialization.Serializable + +@Serializable +data class NoteDto( + val id: String, + val folderId: String?, + val body: NoteBodyDto, + val metadata: NoteMetaDto, +) + +@Serializable +data class NoteBodyDto( + val title: String, + val content: String, + val summary: String?, +) + +@Serializable +data class NoteMetaDto( + val createdAt: Long, + val updatedAt: Long, + val tags: String?, + val isFavorite: Boolean, +) From 46983040462c9b0929be0e76a76d6d26b5437531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 13:44:48 +0300 Subject: [PATCH 15/25] feat: implement NoteEntityJsonConverter class --- .../data/mapper/NoteEntityJsonConverter.kt | 62 ++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt b/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt index 7bb836d..98168f0 100644 --- a/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt +++ b/data/src/main/java/com/itlab/data/mapper/NoteEntityJsonConverter.kt @@ -1,4 +1,64 @@ package com.itlab.data.mapper -class NoteEntityJsonConverter { +import com.itlab.data.entity.NoteEntity +import com.itlab.data.model.NoteBodyDto +import com.itlab.data.model.NoteDto +import com.itlab.data.model.NoteMetaDto +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +class NoteEntityJsonConverter( + private val json: Json = + Json { + ignoreUnknownKeys = true + encodeDefaults = true + }, +) { + fun NoteEntity.toDto(): NoteDto = + NoteDto( + id = id, + folderId = folderId, + body = + NoteBodyDto( + title = title, + content = content, + summary = summary, + ), + metadata = + NoteMetaDto( + createdAt = createdAt.toEpochMilliseconds(), + updatedAt = updatedAt.toEpochMilliseconds(), + tags = tags, + isFavorite = isFavorite, + ), + ) + + fun NoteEntity.toJson(): String { + val dto = this.toDto() + return json.encodeToString(dto) + } + + fun toEntity( + jsonString: String, + userId: String, + ): NoteEntity { + val dto = json.decodeFromString(jsonString) + return dto.toEntity(userId) + } + + fun NoteDto.toEntity(userId: String): NoteEntity = + NoteEntity( + id = id, + userId = userId, + title = body.title, + content = body.content, + folderId = folderId, + createdAt = kotlinx.datetime.Instant.fromEpochMilliseconds(metadata.createdAt), + updatedAt = kotlinx.datetime.Instant.fromEpochMilliseconds(metadata.updatedAt), + tags = metadata.tags, + isFavorite = metadata.isFavorite, + isSynced = true, + isDeleted = false, + summary = body.summary, + ) } From a6a7a7e5153adec1d87b207895ba50c037613fbd Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 17 Apr 2026 15:17:19 +0200 Subject: [PATCH 16/25] chore: for pull --- data/lint-baseline.xml | 4 ++-- data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt diff --git a/data/lint-baseline.xml b/data/lint-baseline.xml index bc36162..bf11888 100644 --- a/data/lint-baseline.xml +++ b/data/lint-baseline.xml @@ -5,14 +5,14 @@ id="InvalidPackage" message="Invalid package reference in library; not included in Android: `javax.naming.directory`. Referenced from `io.grpc.internal.JndiResourceResolverFactory.JndiRecordFetcher`."> + file="../../.gradle/caches/modules-2/files-2.1/io.grpc/grpc-core/1.62.2/5808049a5e33eba6f248a68d58e75399a68f2784/grpc-core-1.62.2.jar"/> + file="../../.gradle/caches/modules-2/files-2.1/io.grpc/grpc-core/1.62.2/5808049a5e33eba6f248a68d58e75399a68f2784/grpc-core-1.62.2.jar"/> diff --git a/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt b/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt new file mode 100644 index 0000000..e69de29 From 7c556c80835b5c22e0977d19366ed9a888deddc0 Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 17 Apr 2026 17:03:57 +0300 Subject: [PATCH 17/25] feat: add class SyncManagerImpl --- .../com/itlab/data/cloud/SyncManagerImpl.kt | 93 +++++++++++++++++++ .../main/java/com/itlab/domain/model/Note.kt | 4 +- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt b/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt index e69de29..3b3c2a8 100644 --- a/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt +++ b/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt @@ -0,0 +1,93 @@ +package com.itlab.data.cloud + +import com.itlab.data.dao.NoteDao +import com.itlab.data.mapper.NoteEntityJsonConverter +import com.itlab.domain.cloud.CloudDataSource +import com.itlab.domain.cloud.Result +import com.itlab.domain.cloud.SyncManager +import com.itlab.domain.cloud.SyncState +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first +import timber.log.Timber + +class SyncManagerImpl( + private val noteDao: NoteDao, + private val cloudDataSource: CloudDataSource, + private val jsonConverter: NoteEntityJsonConverter +) : SyncManager { + + private val _syncState = MutableStateFlow(SyncState.Idle) + override val syncState: StateFlow = _syncState.asStateFlow() + + override suspend fun sync(userId: String) { + _syncState.value = SyncState.Syncing + + try { + pushChanges(userId) + pullUpdates(userId) + + _syncState.value = SyncState.Success + } catch (e: Exception) { + Timber.e(e, "Synchronization was interrupted due to an error") + _syncState.value = SyncState.Error(e.message ?: "Unknown error") + throw e + } + } + + override suspend fun pushChanges(userId: String) { + val unsyncedEntities = noteDao.getUnsyncedNotes() + + for (entity in unsyncedEntities) { + val json = with(jsonConverter) { entity.toJson() } + + val result = cloudDataSource.uploadNote(entity.id, json) + + when (result) { + is Result.Success -> { + val syncedEntity = entity.copy(isSynced = true) + noteDao.update(syncedEntity) + } + is Result.Error -> { + Timber.e(result.exception, "Couldn't upload the note ${entity.id}") + throw result.exception + } + } + } + } + + override suspend fun pullUpdates(userId: String) { + val metadataResult = cloudDataSource.listNoteMetadata(userId) + + val remoteMetadata = when (metadataResult) { + is Result.Success -> metadataResult.data + is Result.Error -> throw metadataResult.exception + } + + val localNotes = noteDao.getAllNotes().first() + val localIds = localNotes.map { it.id } + + val toDownload = remoteMetadata.filter { cloudMeta -> + cloudMeta.key !in localIds + } + + for (meta in toDownload) { + val downloadResult = cloudDataSource.downloadNote(meta.key) + + when (downloadResult) { + is Result.Success -> { + val entity = jsonConverter.toEntity( + jsonString = downloadResult.data, + userId = userId + ) + noteDao.insert(entity) + } + is Result.Error -> { + Timber.e(downloadResult.exception, "Couldn't download the note ${meta.key}") + throw downloadResult.exception + } + } + } + } +} diff --git a/domain/src/main/java/com/itlab/domain/model/Note.kt b/domain/src/main/java/com/itlab/domain/model/Note.kt index e3a0067..14fc9fd 100644 --- a/domain/src/main/java/com/itlab/domain/model/Note.kt +++ b/domain/src/main/java/com/itlab/domain/model/Note.kt @@ -18,7 +18,7 @@ data class Note( val tags: Set = emptySet(), val isFavorite: Boolean = false, val summary: String? = null, - val syncStatus: SyncStatus = SyncStatus.PENDING, + val syncStatus: SyncState = SyncState.PENDING, ) @Serializable @@ -67,7 +67,7 @@ enum class TextFormat { HTML, } -enum class SyncStatus { +enum class SyncState { SYNCED, PENDING, SYNCING, From ec775b71226a7c0b7e74d79eddb1bb58b2d6adfb Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 17 Apr 2026 17:18:13 +0300 Subject: [PATCH 18/25] fix: fix build --- .../com/itlab/data/cloud/SyncManagerImpl.kt | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt b/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt index 3b3c2a8..21897de 100644 --- a/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt +++ b/data/src/main/java/com/itlab/data/cloud/SyncManagerImpl.kt @@ -6,18 +6,20 @@ import com.itlab.domain.cloud.CloudDataSource import com.itlab.domain.cloud.Result import com.itlab.domain.cloud.SyncManager import com.itlab.domain.cloud.SyncState +import kotlinx.coroutines.CancellationException import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.first +import kotlinx.serialization.SerializationException import timber.log.Timber +import java.io.IOException class SyncManagerImpl( private val noteDao: NoteDao, private val cloudDataSource: CloudDataSource, - private val jsonConverter: NoteEntityJsonConverter + private val jsonConverter: NoteEntityJsonConverter, ) : SyncManager { - private val _syncState = MutableStateFlow(SyncState.Idle) override val syncState: StateFlow = _syncState.asStateFlow() @@ -29,13 +31,30 @@ class SyncManagerImpl( pullUpdates(userId) _syncState.value = SyncState.Success - } catch (e: Exception) { - Timber.e(e, "Synchronization was interrupted due to an error") - _syncState.value = SyncState.Error(e.message ?: "Unknown error") + } catch (e: kotlinx.coroutines.CancellationException) { + throw e + } catch (e: CancellationException) { + throw e + } catch (e: IOException) { + handleError("Network error during sync", e) + throw e + } catch (e: SerializationException) { + handleError("Data parsing error", e) + throw e + } catch (e: IllegalStateException) { + handleError("Invalid state during sync", e) throw e } } + private fun handleError( + message: String, + e: Exception, + ) { + Timber.e(e, message) + _syncState.value = SyncState.Error(e.message ?: "Unknown error") + } + override suspend fun pushChanges(userId: String) { val unsyncedEntities = noteDao.getUnsyncedNotes() @@ -60,27 +79,30 @@ class SyncManagerImpl( override suspend fun pullUpdates(userId: String) { val metadataResult = cloudDataSource.listNoteMetadata(userId) - val remoteMetadata = when (metadataResult) { - is Result.Success -> metadataResult.data - is Result.Error -> throw metadataResult.exception - } + val remoteMetadata = + when (metadataResult) { + is Result.Success -> metadataResult.data + is Result.Error -> throw metadataResult.exception + } val localNotes = noteDao.getAllNotes().first() val localIds = localNotes.map { it.id } - val toDownload = remoteMetadata.filter { cloudMeta -> - cloudMeta.key !in localIds - } + val toDownload = + remoteMetadata.filter { cloudMeta -> + cloudMeta.key !in localIds + } for (meta in toDownload) { val downloadResult = cloudDataSource.downloadNote(meta.key) when (downloadResult) { is Result.Success -> { - val entity = jsonConverter.toEntity( - jsonString = downloadResult.data, - userId = userId - ) + val entity = + jsonConverter.toEntity( + jsonString = downloadResult.data, + userId = userId, + ) noteDao.insert(entity) } is Result.Error -> { From 1b50bbbbaf5f322f8be60b7e8ebbb3b4e4b6ef8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:19:00 +0300 Subject: [PATCH 19/25] refactor: remove @Searizable annotations --- data/src/main/java/com/itlab/data/model/ContentItemDto.kt | 4 ++++ domain/src/main/java/com/itlab/domain/model/Note.kt | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) create mode 100644 data/src/main/java/com/itlab/data/model/ContentItemDto.kt diff --git a/data/src/main/java/com/itlab/data/model/ContentItemDto.kt b/data/src/main/java/com/itlab/data/model/ContentItemDto.kt new file mode 100644 index 0000000..22fe586 --- /dev/null +++ b/data/src/main/java/com/itlab/data/model/ContentItemDto.kt @@ -0,0 +1,4 @@ +package com.itlab.data.model + +class ContentItemDto { +} diff --git a/domain/src/main/java/com/itlab/domain/model/Note.kt b/domain/src/main/java/com/itlab/domain/model/Note.kt index e3a0067..b408d44 100644 --- a/domain/src/main/java/com/itlab/domain/model/Note.kt +++ b/domain/src/main/java/com/itlab/domain/model/Note.kt @@ -2,7 +2,6 @@ package com.itlab.domain.model import kotlinx.datetime.Clock import kotlinx.datetime.Instant -import kotlinx.serialization.Serializable import java.util.Collections.emptyList import java.util.Collections.emptySet import java.util.UUID @@ -21,7 +20,6 @@ data class Note( val syncStatus: SyncStatus = SyncStatus.PENDING, ) -@Serializable data class DataSource( val localPath: String? = null, val remoteUrl: String? = null, @@ -29,15 +27,12 @@ data class DataSource( val displayPath: String? get() = localPath ?: remoteUrl } -@Serializable sealed class ContentItem { - @Serializable data class Text( val text: String, val format: TextFormat = TextFormat.PLAIN, ) : ContentItem() - @Serializable data class Image( val source: DataSource, val mimeType: String, @@ -45,7 +40,6 @@ sealed class ContentItem { val height: Int? = null, ) : ContentItem() - @Serializable data class File( val source: DataSource, val mimeType: String, @@ -53,14 +47,12 @@ sealed class ContentItem { val size: Long? = null, ) : ContentItem() - @Serializable data class Link( val url: String, val title: String? = null, ) : ContentItem() } -@Serializable enum class TextFormat { PLAIN, MARKDOWN, From a7f3a2dc81e63e0e18128ac32eda30ac042bdc0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:20:42 +0300 Subject: [PATCH 20/25] feat: implement ContentItemDto sealed class --- .../com/itlab/data/model/ContentItemDto.kt | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/com/itlab/data/model/ContentItemDto.kt b/data/src/main/java/com/itlab/data/model/ContentItemDto.kt index 22fe586..ce3e985 100644 --- a/data/src/main/java/com/itlab/data/model/ContentItemDto.kt +++ b/data/src/main/java/com/itlab/data/model/ContentItemDto.kt @@ -1,4 +1,53 @@ package com.itlab.data.model -class ContentItemDto { +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +sealed class ContentItemDto { + @Serializable + data class Text( + val text: String, + val format: TextFormatDto = TextFormatDto.PLAIN, + ) : ContentItemDto() + + @Serializable + data class Image( + val source: DataSourceDto, + val mimeType: String, + val width: Int? = null, + val height: Int? = null, + ) : ContentItemDto() + + @Serializable + data class File( + val source: DataSourceDto, + val mimeType: String, + val name: String, + val size: Long? = null, + ) : ContentItemDto() + + @Serializable + data class Link( + val url: String, + val title: String? = null, + ) : ContentItemDto() } + +@Serializable +enum class TextFormatDto { + @SerialName("PLAIN") + PLAIN, + + @SerialName("MARKDOWN") + MARKDOWN, + + @SerialName("HTML") + HTML, +} + +@Serializable +data class DataSourceDto( + val localPath: String? = null, + val remoteUrl: String? = null, +) From bd0999fa9547b8ada0efc7db8357b116a7394e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:21:34 +0300 Subject: [PATCH 21/25] feat: implement ContentItemMapper --- .../itlab/data/mapper/ContentItemMapper.kt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 data/src/main/java/com/itlab/data/mapper/ContentItemMapper.kt diff --git a/data/src/main/java/com/itlab/data/mapper/ContentItemMapper.kt b/data/src/main/java/com/itlab/data/mapper/ContentItemMapper.kt new file mode 100644 index 0000000..3ecfd29 --- /dev/null +++ b/data/src/main/java/com/itlab/data/mapper/ContentItemMapper.kt @@ -0,0 +1,32 @@ +package com.itlab.data.mapper + +import com.itlab.data.model.ContentItemDto +import com.itlab.data.model.DataSourceDto +import com.itlab.data.model.TextFormatDto +import com.itlab.domain.model.ContentItem +import com.itlab.domain.model.DataSource +import com.itlab.domain.model.TextFormat + +fun ContentItem.toDto(): ContentItemDto = + when (this) { + is ContentItem.Text -> ContentItemDto.Text(text, format.toDto()) + is ContentItem.Image -> ContentItemDto.Image(source.toDto(), mimeType, width, height) + is ContentItem.File -> ContentItemDto.File(source.toDto(), mimeType, name, size) + is ContentItem.Link -> ContentItemDto.Link(url, title) + } + +fun ContentItemDto.toDomain(): ContentItem = + when (this) { + is ContentItemDto.Text -> ContentItem.Text(text, format.toDomain()) + is ContentItemDto.Image -> ContentItem.Image(source.toDomain(), mimeType, width, height) + is ContentItemDto.File -> ContentItem.File(source.toDomain(), mimeType, name, size) + is ContentItemDto.Link -> ContentItem.Link(url, title) + } + +fun DataSource.toDto() = DataSourceDto(localPath, remoteUrl) + +fun DataSourceDto.toDomain() = DataSource(localPath, remoteUrl) + +fun TextFormat.toDto() = TextFormatDto.valueOf(this.name) + +fun TextFormatDto.toDomain() = TextFormat.valueOf(this.name) From c993be28605b386a69aa1def84b45453903eb729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:23:41 +0300 Subject: [PATCH 22/25] fix: modify NoteMapper class to reflect the changes --- .../java/com/itlab/data/mapper/NoteMapper.kt | 22 ++++++++++++++++--- .../com/itlab/data/mapper/NoteMapperTest.kt | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt index 204f004..9c4356d 100644 --- a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt +++ b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt @@ -2,8 +2,12 @@ package com.itlab.data.mapper import com.itlab.data.entity.MediaEntity import com.itlab.data.entity.NoteEntity +import com.itlab.data.mapper.toDomain +import com.itlab.data.mapper.toDto +import com.itlab.data.model.ContentItemDto import com.itlab.domain.model.ContentItem import com.itlab.domain.model.Note +import com.itlab.domain.model.SyncStatus import kotlinx.serialization.SerializationException import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -31,12 +35,12 @@ class NoteMapper( userId = note.userId, title = note.title, folderId = note.folderId, - content = json.encodeToString(note.contentItems), + content = serializeContent(note.contentItems), createdAt = note.createdAt, updatedAt = note.updatedAt, tags = json.encodeToString(note.tags), isFavorite = note.isFavorite, - isSynced = false, + isSynced = note.syncStatus == SyncStatus.SYNCED, summary = note.summary, ) @@ -46,7 +50,7 @@ class NoteMapper( fun toDomain(entity: NoteEntity): Note { val items = try { - json.decodeFromString>(entity.content) + deserializeContent(entity.content) } catch (e: SerializationException) { Timber.e(e, "Note content mapping failed for entity: ${entity.id}") emptyList() @@ -70,6 +74,8 @@ class NoteMapper( updatedAt = entity.updatedAt, tags = tags, isFavorite = entity.isFavorite, + syncStatus = if (entity.isSynced) SyncStatus.SYNCED else SyncStatus.PENDING, + summary = entity.summary, ) } @@ -94,4 +100,14 @@ class NoteMapper( size = (item as? ContentItem.File)?.size, ) } + + fun serializeContent(items: List): String { + val dtos = items.map { it.toDto() } + return json.encodeToString(dtos) + } + + fun deserializeContent(jsonString: String): List { + val dtos = json.decodeFromString>(jsonString) + return dtos.map { it.toDomain() } + } } diff --git a/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt index a382ded..68d2033 100644 --- a/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt +++ b/data/src/test/java/com/itlab/data/mapper/NoteMapperTest.kt @@ -58,7 +58,7 @@ class NoteMapperTest { assertEquals("[\"money\",\"market\"]", entity.tags) - val decodedItems = Json.decodeFromString>(entity.content) + val decodedItems = mapper.deserializeContent((entity.content)) assertEquals(note.contentItems, decodedItems) @@ -130,7 +130,7 @@ class NoteMapperTest { userId = testUserId, title = "Test Note", folderId = "fuid-100", - content = json.encodeToString>(originalItems), + content = mapper.serializeContent(originalItems), tags = json.encodeToString>(originalTags), isFavorite = true, createdAt = testTime, From 275b4bc95d79a0e8248febe47240b3346366866f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=A1=D0=BC=D0=B8?= =?UTF-8?q?=D1=80=D0=BD=D0=BE=D0=B2?= <152095229+N1smi@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:29:07 +0300 Subject: [PATCH 23/25] fix: fix build --- data/src/main/java/com/itlab/data/mapper/NoteMapper.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt index 9c4356d..8d0fea6 100644 --- a/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt +++ b/data/src/main/java/com/itlab/data/mapper/NoteMapper.kt @@ -7,7 +7,7 @@ import com.itlab.data.mapper.toDto import com.itlab.data.model.ContentItemDto import com.itlab.domain.model.ContentItem import com.itlab.domain.model.Note -import com.itlab.domain.model.SyncStatus +import com.itlab.domain.model.SyncState import kotlinx.serialization.SerializationException import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @@ -40,7 +40,7 @@ class NoteMapper( updatedAt = note.updatedAt, tags = json.encodeToString(note.tags), isFavorite = note.isFavorite, - isSynced = note.syncStatus == SyncStatus.SYNCED, + isSynced = note.syncStatus == SyncState.SYNCED, summary = note.summary, ) @@ -74,7 +74,7 @@ class NoteMapper( updatedAt = entity.updatedAt, tags = tags, isFavorite = entity.isFavorite, - syncStatus = if (entity.isSynced) SyncStatus.SYNCED else SyncStatus.PENDING, + syncStatus = if (entity.isSynced) SyncState.SYNCED else SyncState.PENDING, summary = entity.summary, ) } From 71c906dee8ef2b4ef62bd43177595221721d0f3f Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 17 Apr 2026 18:25:55 +0300 Subject: [PATCH 24/25] delete empty file --- data/lint-baseline.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/lint-baseline.xml diff --git a/data/lint-baseline.xml b/data/lint-baseline.xml deleted file mode 100644 index e69de29..0000000 From fd0f2716967b108d883a12b0b39191156c5c2711 Mon Sep 17 00:00:00 2001 From: sannarat Date: Fri, 17 Apr 2026 18:49:36 +0300 Subject: [PATCH 25/25] fix: fix build --- app/src/main/AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9846e5f..161467b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ xmlns:tools="http://schemas.android.com/tools">