currentSelection;
+ private boolean isMulti;
+ private boolean canSelectSelf;
+ private boolean resetPositionOnCommit = false;
private ListClickListener listClickListener = new ListClickListener();
@Nullable private SwipeRefreshLayout.OnRefreshListener onRefreshListener;
@@ -161,7 +161,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
if (context instanceof FindByCallback) {
- findByCallback = (FindByCallback) context;
+ showFindByUsernameAndPhoneOptions((FindByCallback) context);
}
if (context instanceof NewCallCallback) {
@@ -177,11 +177,11 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
if (getParentFragment() instanceof OnContactSelectedListener) {
- onContactSelectedListener = (OnContactSelectedListener) getParentFragment();
+ setOnContactSelectedListener((OnContactSelectedListener) getParentFragment());
}
if (context instanceof OnContactSelectedListener) {
- onContactSelectedListener = (OnContactSelectedListener) context;
+ setOnContactSelectedListener((OnContactSelectedListener) context);
}
if (context instanceof OnSelectionLimitReachedListener) {
@@ -209,6 +209,14 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
}
+ public void showFindByUsernameAndPhoneOptions(@Nullable FindByCallback callback) {
+ this.findByCallback = callback;
+ }
+
+ public void setOnContactSelectedListener(@Nullable OnContactSelectedListener listener) {
+ this.onContactSelectedListener = listener;
+ }
+
@Override
public void onActivityCreated(Bundle icicle) {
super.onActivityCreated(icicle);
@@ -221,7 +229,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
super.onStart();
if (hasContactsPermissions(requireContext()) && !TextSecurePreferences.hasSuccessfullyRetrievedDirectory(getActivity())) {
- handleContactPermissionGranted();
+ handleContactPermissionGranted();
} else {
requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
contactSearchMediator.refresh();
@@ -232,13 +240,13 @@ public final class ContactSelectionListFragment extends LoggingFragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contact_selection_list_fragment, container, false);
- emptyText = view.findViewById(android.R.id.empty);
- recyclerView = view.findViewById(R.id.recycler_view);
- swipeRefresh = view.findViewById(R.id.swipe_refresh);
- fastScroller = view.findViewById(R.id.fast_scroller);
- chipRecycler = view.findViewById(R.id.chipRecycler);
- constraintLayout = view.findViewById(R.id.container);
- headerActionView = view.findViewById(R.id.header_action);
+ emptyText = view.findViewById(android.R.id.empty);
+ recyclerView = view.findViewById(R.id.recycler_view);
+ swipeRefresh = view.findViewById(R.id.swipe_refresh);
+ fastScroller = view.findViewById(R.id.fast_scroller);
+ chipRecycler = view.findViewById(R.id.chipRecycler);
+ constraintLayout = view.findViewById(R.id.container);
+ headerActionView = view.findViewById(R.id.header_action);
final LinearLayoutManager layoutManager = new LinearLayoutManager(requireContext());
@@ -441,7 +449,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
@Override
public void onDestroyView() {
super.onDestroyView();
- constraintLayout = null;
+ constraintLayout = null;
onRefreshListener = null;
}
@@ -723,7 +731,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
SimpleTask.run(getViewLifecycleOwner().getLifecycle(), () -> {
return UsernameRepository.fetchAciForUsername(UsernameUtil.sanitizeUsernameFromSearch(username));
- }, result -> {
+ }, result -> {
loadingDialog.dismiss();
// TODO Could be more specific with errors
@@ -756,10 +764,10 @@ public final class ContactSelectionListFragment extends LoggingFragment {
selectedContact.getNumber(),
Optional.empty(),
allowed -> {
- if (allowed) {
- markContactSelected(selectedContact);
- }
- });
+ if (allowed) {
+ markContactSelected(selectedContact);
+ }
+ });
} else {
markContactSelected(selectedContact);
}
@@ -913,9 +921,10 @@ public final class ContactSelectionListFragment extends LoggingFragment {
builder.setQuery(contactSearchState.getQuery());
if ((newConversationCallback != null || findByCallback != null) &&
- !hasContactsPermissions(requireContext()) &&
+ !hasContactsPermissions(requireContext()) &&
!SignalStore.uiHints().getDismissedContactsPermissionBanner() &&
- !hasQuery) {
+ !hasQuery)
+ {
builder.arbitrary(ContactSelectionListAdapter.ArbitraryRepository.ArbitraryRow.FIND_CONTACTS_BANNER.getCode());
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java
index 11fff39882..3225dbfd9e 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/ContactFilterView.java
@@ -25,8 +25,13 @@ import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ViewUtil;
+/**
+ * A search input field for finding recipients.
+ *
+ * In compose, use RecipientSearchField instead.
+ */
public final class ContactFilterView extends FrameLayout {
- private OnFilterChangedListener listener;
+ private OnFilterChangedListener listener;
private final EditText searchText;
private final AnimatingToggle toggle;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/compose/ScreenTitlePane.kt b/app/src/main/java/org/thoughtcrime/securesms/components/compose/ScreenTitlePane.kt
new file mode 100644
index 0000000000..81c2338fcd
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/compose/ScreenTitlePane.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.components.compose
+
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import org.thoughtcrime.securesms.window.WindowSizeClass
+
+/**
+ * Displays the screen title for split-pane UIs on tablets and foldable devices.
+ */
+@Composable
+fun ScreenTitlePane(
+ title: String,
+ modifier: Modifier = Modifier
+) {
+ val windowSizeClass = WindowSizeClass.rememberWindowSizeClass()
+
+ Text(
+ text = title,
+ style = MaterialTheme.typography.headlineLarge,
+ color = MaterialTheme.colorScheme.onSurface,
+ modifier = modifier
+ .padding(
+ start = if (windowSizeClass.isExtended()) 80.dp else 20.dp,
+ end = 20.dp,
+ top = 12.dp,
+ bottom = 12.dp
+ )
+ )
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationActivityV2.kt
new file mode 100644
index 0000000000..2200949ca3
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationActivityV2.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.conversation
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.widthIn
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import org.signal.core.ui.compose.AllDevicePreviews
+import org.signal.core.ui.compose.Previews
+import org.signal.core.ui.compose.Scaffolds
+import org.signal.core.ui.compose.theme.SignalTheme
+import org.thoughtcrime.securesms.PassphraseRequiredActivity
+import org.thoughtcrime.securesms.R
+import org.thoughtcrime.securesms.components.compose.ScreenTitlePane
+import org.thoughtcrime.securesms.util.viewModel
+import org.thoughtcrime.securesms.window.AppScaffoldWithTopBar
+import org.thoughtcrime.securesms.window.WindowSizeClass
+import org.thoughtcrime.securesms.window.rememberAppScaffoldNavigator
+
+/**
+ * Allows the user to start a new conversation by selecting a recipient.
+ *
+ * A modernized compose-based replacement for [org.thoughtcrime.securesms.NewConversationActivity].
+ */
+class NewConversationActivityV2 : PassphraseRequiredActivity() {
+ companion object {
+ @JvmStatic
+ fun createIntent(context: Context): Intent = Intent(context, NewConversationActivityV2::class.java)
+ }
+
+ private val viewModel by viewModel { NewConversationViewModel() }
+
+ override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
+ super.onCreate(savedInstanceState, ready)
+
+ setContent {
+ val uiState by viewModel.uiState.collectAsStateWithLifecycle()
+
+ SignalTheme {
+ NewConversationScreen(
+ uiState = uiState,
+ callbacks = object : Callbacks {
+ override fun onBackPressed() = onBackPressedDispatcher.onBackPressed()
+ }
+ )
+ }
+ }
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3AdaptiveApi::class)
+@Composable
+private fun NewConversationScreen(
+ uiState: NewConversationUiState,
+ callbacks: Callbacks
+) {
+ val windowSizeClass = WindowSizeClass.rememberWindowSizeClass()
+ val isSplitPane = windowSizeClass.isSplitPane(forceSplitPaneOnCompactLandscape = uiState.forceSplitPaneOnCompactLandscape)
+
+ AppScaffoldWithTopBar(
+ topBarContent = {
+ Scaffolds.DefaultTopAppBar(
+ title = if (!isSplitPane) stringResource(R.string.NewConversationActivity__new_message) else "",
+ titleContent = { _, title -> Text(text = title, style = MaterialTheme.typography.titleLarge) },
+ navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24),
+ navigationContentDescription = stringResource(R.string.DefaultTopAppBar__navigate_up_content_description),
+ onNavigationClick = callbacks::onBackPressed
+ )
+ },
+ listContent = {
+ if (isSplitPane) {
+ ScreenTitlePane(
+ title = stringResource(R.string.NewConversationActivity__new_message),
+ modifier = Modifier.fillMaxSize()
+ )
+ } else {
+ DetailPaneContent()
+ }
+ },
+
+ detailContent = {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier.fillMaxSize()
+ ) {
+ DetailPaneContent(
+ modifier = Modifier
+ .widthIn(max = windowSizeClass.detailPaneMaxContentWidth)
+ )
+ }
+ },
+
+ navigator = rememberAppScaffoldNavigator(
+ isSplitPane = isSplitPane
+ )
+ )
+}
+
+private interface Callbacks {
+ fun onBackPressed()
+
+ object Empty : Callbacks {
+ override fun onBackPressed() = Unit
+ }
+}
+
+@Composable
+private fun DetailPaneContent(
+ modifier: Modifier = Modifier
+) {
+ RecipientPicker(
+ showFindByUsernameAndPhoneOptions = true,
+ callbacks = RecipientPickerCallbacks.Empty, // TODO(jeffrey) implement callbacks
+ modifier = modifier
+ .fillMaxSize()
+ .padding(vertical = 12.dp)
+ )
+}
+
+@AllDevicePreviews
+@Composable
+private fun NewConversationScreenPreview() {
+ Previews.Preview {
+ NewConversationScreen(
+ uiState = NewConversationUiState(
+ forceSplitPaneOnCompactLandscape = false
+ ),
+ callbacks = Callbacks.Empty
+ )
+ }
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationViewModel.kt
new file mode 100644
index 0000000000..1720d95707
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/NewConversationViewModel.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.conversation
+
+import androidx.lifecycle.ViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import org.thoughtcrime.securesms.keyvalue.SignalStore
+
+class NewConversationViewModel : ViewModel() {
+ private val _uiState = MutableStateFlow(NewConversationUiState())
+ val uiState: StateFlow = _uiState.asStateFlow()
+}
+
+data class NewConversationUiState(
+ val forceSplitPaneOnCompactLandscape: Boolean = SignalStore.internal.forceSplitPaneOnCompactLandscape
+)
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/RecipientPicker.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/RecipientPicker.kt
new file mode 100644
index 0000000000..7cc81a7727
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/RecipientPicker.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.conversation
+
+import androidx.annotation.StringRes
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import androidx.fragment.compose.rememberFragmentState
+import org.signal.core.ui.compose.DayNightPreviews
+import org.signal.core.ui.compose.Fragments
+import org.thoughtcrime.securesms.ContactSelectionListFragment
+import org.thoughtcrime.securesms.components.ContactFilterView
+import org.thoughtcrime.securesms.recipients.RecipientId
+
+/**
+ * Provides a recipient search and selection UI.
+ */
+@Composable
+fun RecipientPicker(
+ showFindByUsernameAndPhoneOptions: Boolean,
+ callbacks: RecipientPickerCallbacks,
+ modifier: Modifier = Modifier
+) {
+ var searchQuery by rememberSaveable { mutableStateOf("") }
+
+ Column(
+ modifier = modifier
+ ) {
+ RecipientSearchField(
+ onFilterChanged = { filter ->
+ searchQuery = filter
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp)
+ )
+
+ RecipientSearchResultsList(
+ searchQuery = searchQuery,
+ showFindByUsernameAndPhoneOptions = showFindByUsernameAndPhoneOptions,
+ callbacks = callbacks,
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(top = 8.dp)
+ )
+ }
+}
+
+/**
+ * A search input field for finding recipients.
+ *
+ * Intended to be a compose-based replacement for [ContactFilterView].
+ */
+@Composable
+private fun RecipientSearchField(
+ onFilterChanged: (String) -> Unit,
+ @StringRes hintText: Int? = null,
+ modifier: Modifier = Modifier
+) {
+ val context = LocalContext.current
+ val wrappedView = remember {
+ ContactFilterView(context, null, 0).apply {
+ hintText?.let { setHint(it) }
+ }
+ }
+
+ DisposableEffect(onFilterChanged) {
+ wrappedView.setOnFilterChangedListener { filter -> onFilterChanged(filter) }
+ onDispose {
+ wrappedView.setOnFilterChangedListener(null)
+ }
+ }
+
+ AndroidView(
+ factory = { wrappedView },
+ modifier = modifier
+ )
+}
+
+@Composable
+private fun RecipientSearchResultsList(
+ searchQuery: String,
+ showFindByUsernameAndPhoneOptions: Boolean,
+ callbacks: RecipientPickerCallbacks,
+ modifier: Modifier = Modifier
+) {
+ val fragmentState = rememberFragmentState()
+ var currentFragment by remember { mutableStateOf(null) }
+
+ Fragments.Fragment(
+ fragmentState = fragmentState,
+ onUpdate = { fragment ->
+ currentFragment = fragment
+ currentFragment?.view?.setPadding(0, 0, 0, 0)
+
+ if (showFindByUsernameAndPhoneOptions) {
+ fragment.showFindByUsernameAndPhoneOptions(object : ContactSelectionListFragment.FindByCallback {
+ override fun onFindByUsername() = callbacks.onFindByUsernameClicked()
+ override fun onFindByPhoneNumber() = callbacks.onFindByPhoneNumberClicked()
+ })
+ }
+ },
+ modifier = modifier
+ )
+
+ var previousQueryText by rememberSaveable { mutableStateOf("") }
+ LaunchedEffect(searchQuery) {
+ if (previousQueryText != searchQuery) {
+ if (searchQuery.isNotBlank()) {
+ currentFragment?.setQueryFilter(searchQuery)
+ } else {
+ currentFragment?.resetQueryFilter()
+ }
+ previousQueryText = searchQuery
+ }
+ }
+}
+
+@DayNightPreviews
+@Composable
+private fun RecipientPickerPreview() {
+ RecipientPicker(
+ showFindByUsernameAndPhoneOptions = true,
+ callbacks = RecipientPickerCallbacks.Empty
+ )
+}
+
+interface RecipientPickerCallbacks {
+ fun onFindByUsernameClicked()
+ fun onFindByPhoneNumberClicked()
+ fun onRecipientClicked(id: RecipientId)
+
+ object Empty : RecipientPickerCallbacks {
+ override fun onFindByUsernameClicked() = Unit
+ override fun onFindByPhoneNumberClicked() = Unit
+ override fun onRecipientClicked(id: RecipientId) = Unit
+ }
+}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffold.kt b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffold.kt
index c7cef864a9..66c03831a0 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffold.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffold.kt
@@ -38,6 +38,7 @@ import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.window.core.ExperimentalWindowCoreApi
@@ -86,6 +87,12 @@ enum class WindowSizeClass(
EXTENDED_PORTRAIT(Navigation.RAIL),
EXTENDED_LANDSCAPE(Navigation.RAIL);
+ val listPaneDefaultPreferredWidth: Dp
+ get() = if (isExtended()) 416.dp else 316.dp
+
+ val detailPaneMaxContentWidth: Dp = 624.dp
+ val horizontalPartitionDefaultSpacerSize: Dp = 12.dp
+
fun isCompact(): Boolean = this == COMPACT_PORTRAIT || this == COMPACT_LANDSCAPE
fun isMedium(): Boolean = this == MEDIUM_PORTRAIT || this == MEDIUM_LANDSCAPE
fun isExtended(): Boolean = this == EXTENDED_PORTRAIT || this == EXTENDED_LANDSCAPE
@@ -93,8 +100,11 @@ enum class WindowSizeClass(
fun isLandscape(): Boolean = this == COMPACT_LANDSCAPE || this == MEDIUM_LANDSCAPE || this == EXTENDED_LANDSCAPE
fun isPortrait(): Boolean = !isLandscape()
- fun isSplitPane(): Boolean {
- return if (isLargeScreenSupportEnabled() && SignalStore.internal.forceSplitPaneOnCompactLandscape) {
+ @JvmOverloads
+ fun isSplitPane(
+ forceSplitPaneOnCompactLandscape: Boolean = SignalStore.internal.forceSplitPaneOnCompactLandscape
+ ): Boolean {
+ return if (isLargeScreenSupportEnabled() && forceSplitPaneOnCompactLandscape) {
this != COMPACT_PORTRAIT
} else {
this.navigation != Navigation.BAR
diff --git a/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldNavigator.kt b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldNavigator.kt
index 87681368b7..e59efe3dd3 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldNavigator.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldNavigator.kt
@@ -19,7 +19,9 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.Dp
+import org.thoughtcrime.securesms.keyvalue.SignalStore
/**
* AppScaffoldNavigator wraps a delegate navigator (such as the value returned by [rememberThreePaneScaffoldNavigatorDelegate]
@@ -85,9 +87,12 @@ open class AppScaffoldNavigator @RememberInComposition constructor(private va
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun rememberAppScaffoldNavigator(
- isSplitPane: Boolean,
- horizontalPartitionSpacerSize: Dp,
- defaultPanePreferredWidth: Dp
+ windowSizeClass: WindowSizeClass = WindowSizeClass.rememberWindowSizeClass(),
+ isSplitPane: Boolean = windowSizeClass.isSplitPane(
+ forceSplitPaneOnCompactLandscape = if (LocalInspectionMode.current) false else SignalStore.internal.forceSplitPaneOnCompactLandscape
+ ),
+ horizontalPartitionSpacerSize: Dp = windowSizeClass.horizontalPartitionDefaultSpacerSize,
+ defaultPanePreferredWidth: Dp = windowSizeClass.listPaneDefaultPreferredWidth
): AppScaffoldNavigator {
val delegate = rememberThreePaneScaffoldNavigatorDelegate(
isSplitPane,
diff --git a/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldWithTopBar.kt b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldWithTopBar.kt
new file mode 100644
index 0000000000..32d8426c2f
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/window/AppScaffoldWithTopBar.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.thoughtcrime.securesms.window
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi
+import androidx.compose.material3.adaptive.layout.PaneExpansionState
+import androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope
+import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
+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.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalInspectionMode
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.text.style.TextAlign
+import org.signal.core.ui.compose.AllDevicePreviews
+import org.signal.core.ui.compose.Previews
+import org.signal.core.ui.compose.Scaffolds
+import org.thoughtcrime.securesms.R
+import org.thoughtcrime.securesms.keyvalue.SignalStore
+
+/**
+ * Wraps [AppScaffold], adding a top app bar that spans across both the list and detail panes.
+ */
+@OptIn(ExperimentalMaterial3AdaptiveApi::class)
+@Composable
+fun AppScaffoldWithTopBar(
+ navigator: AppScaffoldNavigator = rememberAppScaffoldNavigator(),
+ topBarContent: @Composable () -> Unit = {},
+ detailContent: @Composable () -> Unit = {},
+ navRailContent: @Composable () -> Unit = {},
+ bottomNavContent: @Composable () -> Unit = {},
+ paneExpansionState: PaneExpansionState = rememberPaneExpansionState(),
+ paneExpansionDragHandle: (@Composable ThreePaneScaffoldScope.(PaneExpansionState) -> Unit)? = null,
+ animatorFactory: AppScaffoldAnimationStateFactory = AppScaffoldAnimationStateFactory.Default,
+ listContent: @Composable () -> Unit
+) {
+ val windowSizeClass = WindowSizeClass.rememberWindowSizeClass()
+ val isSplitPane = windowSizeClass.isSplitPane(
+ forceSplitPaneOnCompactLandscape = if (LocalInspectionMode.current) false else SignalStore.internal.forceSplitPaneOnCompactLandscape
+ )
+
+ if (isSplitPane) {
+ Column {
+ topBarContent()
+
+ AppScaffold(
+ navigator = navigator,
+ detailContent = detailContent,
+ navRailContent = navRailContent,
+ bottomNavContent = bottomNavContent,
+ paneExpansionState = paneExpansionState,
+ paneExpansionDragHandle = paneExpansionDragHandle,
+ animatorFactory = animatorFactory,
+ listContent = listContent
+ )
+ }
+ } else {
+ AppScaffold(
+ navigator = navigator,
+ detailContent = detailContent,
+ navRailContent = navRailContent,
+ bottomNavContent = bottomNavContent,
+ paneExpansionState = paneExpansionState,
+ paneExpansionDragHandle = paneExpansionDragHandle,
+ animatorFactory = animatorFactory,
+ listContent = {
+ Scaffold(topBar = topBarContent) { paddingValues ->
+ Box(modifier = Modifier.padding(paddingValues)) {
+ listContent()
+ }
+ }
+ }
+ )
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3AdaptiveApi::class)
+@AllDevicePreviews
+@Composable
+private fun AppScaffoldWithTopBarPreview() {
+ Previews.Preview {
+ val windowSizeClass = WindowSizeClass.rememberWindowSizeClass()
+ val isSplitPane = windowSizeClass.isSplitPane(forceSplitPaneOnCompactLandscape = false)
+
+ AppScaffoldWithTopBar(
+ navigator = rememberAppScaffoldNavigator(),
+
+ topBarContent = {
+ Scaffolds.DefaultTopAppBar(
+ title = if (!isSplitPane) stringResource(R.string.NewConversationActivity__new_message) else "",
+ titleContent = { _, title -> Text(text = title, style = MaterialTheme.typography.titleLarge) },
+ navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24),
+ navigationContentDescription = "",
+ onNavigationClick = { }
+ )
+ },
+
+ listContent = {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.Red)
+ ) {
+ Text(
+ text = "ListContent\n$windowSizeClass",
+ textAlign = TextAlign.Center
+ )
+ }
+ },
+
+ detailContent = {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.Blue)
+ ) {
+ Text(
+ text = "DetailContent",
+ textAlign = TextAlign.Center
+ )
+ }
+ }
+ )
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fd08a08182..8031391353 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5926,8 +5926,8 @@
- %1$s are not Signal users
-
- Search name or number
+
+ Name, username or number
ยท %1$s
diff --git a/core-ui/build.gradle.kts b/core-ui/build.gradle.kts
index 3aee2cfda5..a13407fe06 100644
--- a/core-ui/build.gradle.kts
+++ b/core-ui/build.gradle.kts
@@ -29,4 +29,5 @@ dependencies {
api(libs.androidx.compose.material3.adaptive.navigation)
api(libs.androidx.compose.ui.tooling.preview)
debugApi(libs.androidx.compose.ui.tooling.core)
+ api(libs.androidx.fragment.compose)
}
diff --git a/core-ui/src/main/java/org/signal/core/ui/compose/Fragments.kt b/core-ui/src/main/java/org/signal/core/ui/compose/Fragments.kt
new file mode 100644
index 0000000000..f65ffd3a39
--- /dev/null
+++ b/core-ui/src/main/java/org/signal/core/ui/compose/Fragments.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2025 Signal Messenger, LLC
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+package org.signal.core.ui.compose
+
+import android.os.Bundle
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+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.platform.LocalInspectionMode
+import androidx.fragment.app.Fragment
+import androidx.fragment.compose.AndroidFragment
+import androidx.fragment.compose.FragmentState
+import androidx.fragment.compose.rememberFragmentState
+import org.signal.core.ui.compose.Fragments.Fragment
+
+object Fragments {
+ /**
+ * Wraps an [Fragment], displaying the fragment at runtime or a placeholder in compose previews to avoid rendering errors that occur when
+ * using [Fragment] in @Preview composables.
+ */
+ @Composable
+ inline fun Fragment(
+ modifier: Modifier = Modifier,
+ fragmentState: FragmentState = rememberFragmentState(),
+ arguments: Bundle = Bundle.EMPTY,
+ noinline onUpdate: (T) -> Unit = { }
+ ) {
+ if (!LocalInspectionMode.current) {
+ AndroidFragment(clazz = T::class.java, modifier, fragmentState, arguments, onUpdate)
+ } else {
+ Text(
+ text = "[${T::class.simpleName}]",
+ style = MaterialTheme.typography.bodyLarge,
+ modifier = modifier
+ .fillMaxSize()
+ .background(Color.Gray)
+ .wrapContentSize(Alignment.Center)
+ )
+ }
+ }
+
+ /**
+ * Wraps an [Fragment], displaying the fragment at runtime or a placeholder in compose previews to avoid rendering errors that occur when
+ * using [Fragment] in @Preview composables.
+ */
+ @Composable
+ fun Fragment(
+ clazz: Class,
+ modifier: Modifier = Modifier,
+ fragmentState: FragmentState = rememberFragmentState(),
+ arguments: Bundle = Bundle.EMPTY,
+ onUpdate: (T) -> Unit = { }
+ ) {
+ if (!LocalInspectionMode.current) {
+ AndroidFragment(clazz = clazz, modifier, fragmentState, arguments, onUpdate)
+ } else {
+ Text(
+ text = "[${clazz.simpleName}]",
+ style = MaterialTheme.typography.bodyLarge,
+ modifier = modifier
+ .fillMaxSize()
+ .background(Color.Gray)
+ .wrapContentSize(Alignment.Center)
+ )
+ }
+ }
+}
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 027523ef4f..54333acda7 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -25,108 +25,158 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -145,6 +195,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -153,9 +205,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -166,275 +222,414 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -445,14 +640,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -463,14 +664,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -481,17 +688,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -505,9 +720,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -521,17 +740,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -545,9 +772,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -561,9 +792,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -577,9 +812,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -593,14 +832,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -614,9 +859,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -630,9 +879,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -646,17 +899,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -670,9 +931,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -686,9 +951,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -702,9 +971,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -715,6 +988,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -728,9 +1003,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -744,9 +1023,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -760,9 +1043,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -776,9 +1063,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -792,9 +1083,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -808,9 +1103,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -824,86 +1123,128 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -930,9 +1271,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -946,9 +1291,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -962,9 +1311,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -978,9 +1331,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -994,9 +1351,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1010,9 +1371,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1034,9 +1399,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1058,14 +1427,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -1087,9 +1462,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1103,17 +1482,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1127,6 +1514,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -1137,9 +1526,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1153,9 +1546,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1169,17 +1566,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1193,9 +1598,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1209,9 +1618,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1225,17 +1638,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1249,9 +1670,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1265,9 +1690,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1281,9 +1710,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1297,9 +1730,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1313,9 +1750,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1329,9 +1770,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1345,9 +1790,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1361,9 +1810,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1377,17 +1830,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1401,9 +1862,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1417,9 +1882,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1433,9 +1902,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1449,9 +1922,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1465,9 +1942,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1481,9 +1962,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1497,9 +1982,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1513,9 +2002,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1529,9 +2022,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1545,9 +2042,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1561,9 +2062,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1577,17 +2082,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1601,9 +2114,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1617,9 +2134,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1633,17 +2154,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -1657,9 +2186,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1673,9 +2206,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1689,161 +2226,247 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1859,6 +2482,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -1874,9 +2499,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -1890,241 +2519,353 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2138,37 +2879,53 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2182,30 +2939,44 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2219,43 +2990,63 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2269,51 +3060,75 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2327,46 +3142,68 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2380,17 +3217,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -2399,6 +3244,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2412,43 +3259,70 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2462,17 +3336,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -2481,6 +3363,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2494,17 +3378,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -2513,6 +3405,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2526,43 +3420,70 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2573,6 +3494,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2581,9 +3504,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2597,14 +3524,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -2618,6 +3551,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2626,9 +3561,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2642,9 +3581,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2655,6 +3598,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2671,22 +3616,32 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -2700,22 +3655,32 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -2729,6 +3694,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2742,25 +3709,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2771,6 +3750,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2779,9 +3760,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2795,14 +3780,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -2816,6 +3807,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2824,9 +3817,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2840,9 +3837,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2851,11 +3852,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2869,35 +3874,51 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2914,6 +3935,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -2922,12 +3945,18 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -2944,20 +3973,30 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -2979,9 +4018,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -2995,19 +4038,27 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -3016,6 +4067,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -3032,19 +4085,27 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -3053,6 +4114,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -3069,9 +4132,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -3080,6 +4147,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -3093,9 +4162,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -3114,6 +4187,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -3127,25 +4202,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3162,14 +4249,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3183,33 +4276,49 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3226,14 +4335,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3247,14 +4362,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3268,9 +4389,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -3284,268 +4409,398 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3559,64 +4814,94 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3625,14 +4910,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3646,14 +4937,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3662,14 +4959,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -3678,17 +4981,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -3710,17 +5021,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -3729,75 +5048,111 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3808,6 +5163,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -3818,11 +5175,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -3838,56 +5199,78 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -3898,11 +5281,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -3913,217 +5300,317 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4139,6 +5626,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4154,16 +5643,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4184,11 +5679,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4209,11 +5708,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4234,21 +5737,29 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -4269,6 +5780,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4284,11 +5797,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4304,11 +5821,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4324,11 +5845,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4344,6 +5869,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4359,11 +5886,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4379,11 +5910,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4399,11 +5934,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4452,17 +5991,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -4479,14 +6026,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4503,11 +6056,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4523,6 +6080,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4538,9 +6097,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4557,22 +6120,32 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -4589,14 +6162,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4613,6 +6192,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4628,14 +6209,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4652,14 +6239,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4676,14 +6269,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -4700,22 +6299,32 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -4737,32 +6346,46 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -4778,6 +6401,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4793,6 +6418,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4813,6 +6440,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4833,6 +6462,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4848,11 +6479,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4873,6 +6508,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4893,6 +6530,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4913,6 +6552,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -4943,11 +6584,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4963,11 +6608,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4983,9 +6632,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -4999,6 +6652,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5014,9 +6669,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5030,6 +6689,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5045,9 +6706,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5061,6 +6726,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5076,9 +6743,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5092,6 +6763,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5107,9 +6780,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5123,6 +6800,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5138,9 +6817,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5154,6 +6837,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5169,9 +6854,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5185,6 +6874,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5195,9 +6886,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5211,6 +6906,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5226,9 +6923,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5242,6 +6943,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5275,9 +6978,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5291,6 +6998,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5306,6 +7015,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5316,254 +7027,364 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -5574,59 +7395,83 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -5637,46 +7482,64 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -5687,6 +7550,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5697,9 +7562,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5713,9 +7582,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5726,6 +7599,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -5739,9 +7614,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -5755,248 +7634,350 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6007,46 +7988,64 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6060,386 +8059,568 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6453,17 +8634,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -6477,49 +8666,73 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6541,22 +8754,32 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -6578,298 +8801,436 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -6880,16 +9241,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -6900,16 +9267,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -6920,16 +9293,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -6940,16 +9319,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -6960,16 +9345,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -6980,21 +9371,29 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -7005,24 +9404,34 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -7036,9 +9445,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7052,9 +9465,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7068,9 +9485,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7084,9 +9505,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7100,9 +9525,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7116,9 +9545,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7132,9 +9565,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7148,9 +9585,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7164,9 +9605,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7180,9 +9625,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7196,9 +9645,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7212,214 +9665,304 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -7430,6 +9973,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7440,165 +9985,233 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -7614,99 +10227,139 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -7720,17 +10373,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -7746,9 +10407,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -7759,6 +10424,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7769,6 +10436,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7779,6 +10448,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7789,6 +10460,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7799,6 +10472,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7809,16 +10484,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -7829,6 +10510,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7839,6 +10522,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7849,6 +10534,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7859,6 +10546,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7869,6 +10558,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7879,6 +10570,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7889,16 +10582,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -7909,6 +10608,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7919,6 +10620,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -7932,14 +10635,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -7953,14 +10662,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -7971,17 +10686,25 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -7998,20 +10721,30 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -8025,14 +10758,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -8043,14 +10782,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -8064,9 +10809,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8077,6 +10826,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8087,11 +10838,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8102,6 +10857,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8112,16 +10869,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -8132,6 +10895,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8142,6 +10907,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8152,6 +10919,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8162,26 +10931,36 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -8192,29 +10971,41 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8225,16 +11016,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -8245,6 +11042,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8260,6 +11059,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8275,6 +11076,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8290,6 +11093,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8305,6 +11110,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8318,9 +11125,13 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8331,68 +11142,96 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8409,6 +11248,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8417,25 +11258,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8444,25 +11297,35 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
@@ -8479,52 +11342,74 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8535,11 +11420,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8555,21 +11444,29 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
@@ -8580,16 +11477,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -8600,46 +11503,64 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8650,41 +11571,57 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8695,11 +11632,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8710,11 +11651,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -8725,6 +11670,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -8735,172 +11682,254 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -8914,99 +11943,147 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9020,25 +12097,37 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9049,148 +12138,218 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9206,6 +12365,8 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
@@ -9221,89 +12382,129 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9314,29 +12515,41 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9347,16 +12560,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -9367,11 +12586,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -9387,16 +12610,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -9407,11 +12636,15 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
@@ -9427,155 +12660,227 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -9586,16 +12891,22 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
@@ -9606,21 +12917,29 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
+
+
+
+
+
+
+
+