Ensure that bottom sheet can scroll (#6661)

* RoomListDeclineInviteMenu: limit room name

Improve preview.
Closes #6659

* Ensure that all the ModalBottomSheet can scroll.

* Update screenshots

* Rename Preview.

* Preview the whole bottom sheet.

* Remove obsolete comment.

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Benoit Marty 2026-04-28 09:43:41 +02:00 committed by GitHub
commit 3878ce000c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 193 additions and 67 deletions

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.appconfig
object ProtectionConfig {
/**
* The maximum length of a room name, to limit attack vectors in room invite.
*/
const val MAX_ROOM_NAME_LENGTH = 128
}

View file

@ -95,7 +95,8 @@ internal fun SelectParentSpaceOptions(
sheetState.hide(coroutineScope) {
displaySelectSpaceBottomSheet = false
}
}
},
scrollable = false,
) {
SelectParentSpaceBottomSheet(
spaces = spaces,

View file

@ -11,6 +11,8 @@ package io.element.android.features.home.impl.roomlist
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@ -43,6 +45,7 @@ fun RoomListContextMenu(
) {
ModalBottomSheet(
onDismissRequest = { eventSink(RoomListEvent.HideContextMenu) },
scrollable = false,
) {
RoomListModalBottomSheetContent(
contextMenu = contextMenu,
@ -91,7 +94,9 @@ private fun RoomListModalBottomSheetContent(
onReportRoomClick: () -> Unit,
) {
Column(
modifier = Modifier.fillMaxWidth()
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
) {
ListItem(
headlineContent = {
@ -212,23 +217,16 @@ private fun RoomListModalBottomSheetContent(
}
}
// TODO This component should be seen in [RoomListView] @Preview but it doesn't show up.
// see: https://issuetracker.google.com/issues/283843380
// Remove this preview when the issue is fixed.
@PreviewsDayNight
@Composable
internal fun RoomListModalBottomSheetContentPreview(
internal fun RoomListContextMenuPreview(
@PreviewParameter(RoomListStateContextMenuShownProvider::class) contextMenu: RoomListState.ContextMenu.Shown
) = ElementPreview {
RoomListModalBottomSheetContent(
RoomListContextMenu(
contextMenu = contextMenu,
canReportRoom = true,
onRoomMarkReadClick = {},
onRoomMarkUnreadClick = {},
onRoomSettingsClick = {},
onLeaveRoomClick = {},
onFavoriteChange = {},
onClearCacheRoomClick = {},
onReportRoomClick = {},
eventSink = {},
)
}

View file

@ -13,16 +13,21 @@ 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.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import io.element.android.appconfig.ProtectionConfig
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.home.impl.R
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.libraries.core.extensions.toSafeLength
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
@ -42,9 +47,14 @@ fun RoomListDeclineInviteMenu(
) {
ModalBottomSheet(
onDismissRequest = { eventSink(RoomListEvent.HideDeclineInviteMenu) },
scrollable = false,
) {
RoomListDeclineInviteMenuContent(
roomName = menu.roomSummary.name ?: menu.roomSummary.roomId.value,
roomName = menu.roomSummary.name?.toSafeLength(
maxLength = ProtectionConfig.MAX_ROOM_NAME_LENGTH,
ellipsize = true,
)
?: menu.roomSummary.roomId.value,
onDeclineClick = {
eventSink(RoomListEvent.HideDeclineInviteMenu)
eventSink(RoomListEvent.DeclineInvite(menu.roomSummary, false))
@ -74,7 +84,8 @@ private fun RoomListDeclineInviteMenuContent(
Column(
modifier = Modifier
.fillMaxWidth()
.padding(all = 16.dp),
.padding(all = 16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
@ -112,16 +123,15 @@ private fun RoomListDeclineInviteMenuContent(
}
}
// TODO This component should be seen in [RoomListView] @Preview but it doesn't show up.
// see: https://issuetracker.google.com/issues/283843380
// Remove this preview when the issue is fixed.
@PreviewsDayNight
@Composable
internal fun RoomListDeclineInviteMenuContentPreview() = ElementPreview {
RoomListDeclineInviteMenuContent(
roomName = "Room name",
onCancelClick = {},
onDeclineClick = {},
internal fun RoomListDeclineInviteMenuPreview(
@PreviewParameter(RoomListStateDeclineInviteMenuShownProvider::class) menu: RoomListState.DeclineInviteMenu.Shown,
) = ElementPreview {
RoomListDeclineInviteMenu(
menu = menu,
canReportRoom = false,
onDeclineAndBlockClick = {},
eventSink = {},
)
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.home.impl.roomlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import io.element.android.features.home.impl.model.RoomListRoomSummary
import io.element.android.features.home.impl.model.aRoomListRoomSummary
open class RoomListStateDeclineInviteMenuShownProvider : PreviewParameterProvider<RoomListState.DeclineInviteMenu.Shown> {
override val values: Sequence<RoomListState.DeclineInviteMenu.Shown>
get() = sequenceOf(
aDeclineInviteMenuShown(),
aDeclineInviteMenuShown(
aRoomListRoomSummary(
name = LoremIpsum(500).values.first(),
)
),
aDeclineInviteMenuShown(
aRoomListRoomSummary(
name = null,
)
),
)
}
internal fun aDeclineInviteMenuShown(
roomSummary: RoomListRoomSummary = aRoomListRoomSummary(),
) = RoomListState.DeclineInviteMenu.Shown(
roomSummary = roomSummary,
)

View file

@ -81,7 +81,8 @@ fun SpaceFiltersView(
if (state is SpaceFiltersState.Selecting) {
state.eventSink(SpaceFiltersEvent.Selecting.Cancel)
}
}
},
scrollable = false,
) {
Box(
modifier = Modifier

View file

@ -262,6 +262,7 @@ private fun InvitePeopleConfirmModal(
ModalBottomSheet(
onDismissRequest = onDismiss,
dragHandle = null,
scrollable = false,
) {
IconTitleSubtitleMolecule(
title = simplePluralStringResource(

View file

@ -156,6 +156,7 @@ fun ActionListView(
sheetState = sheetState,
onDismissRequest = ::onDismiss,
modifier = modifier,
scrollable = false,
) {
ActionListViewContent(
state = state,

View file

@ -75,6 +75,7 @@ fun ResolveVerifiedUserSendFailureView(
.navigationBarsPadding(),
sheetState = sheetState,
onDismissRequest = ::dismiss,
scrollable = true,
) {
IconTitleSubtitleMolecule(
modifier = Modifier.padding(24.dp),

View file

@ -13,6 +13,8 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -74,7 +76,8 @@ internal fun AttachmentsBottomSheet(
sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
),
onDismissRequest = { isVisible = false }
onDismissRequest = { isVisible = false },
scrollable = false,
) {
AttachmentSourcePickerMenu(
state = state,
@ -97,6 +100,7 @@ private fun AttachmentSourcePickerMenu(
modifier = Modifier
.navigationBarsPadding()
.imePadding()
.verticalScroll(rememberScrollState())
) {
ListItem(
modifier = Modifier.clickable { state.eventSink(MessageComposerEvent.PickAttachmentSource.PhotoFromCamera) },

View file

@ -50,7 +50,8 @@ fun CustomReactionBottomSheet(
ModalBottomSheet(
onDismissRequest = ::onDismiss,
sheetState = sheetState,
modifier = modifier
modifier = modifier,
scrollable = false,
) {
val presenter = remember {
EmojiPickerPresenter(

View file

@ -90,7 +90,8 @@ fun ReactionSummaryView(
if (state.target != null) {
ModalBottomSheet(
onDismissRequest = ::onDismiss,
modifier = modifier
modifier = modifier,
scrollable = false,
) {
ReactionSummaryViewContent(summary = state.target)
}

View file

@ -57,7 +57,8 @@ internal fun ReadReceiptBottomSheet(
sheetState.hide()
state.eventSink(ReadReceiptBottomSheetEvent.Dismiss)
}
}
},
scrollable = false,
) {
ReadReceiptBottomSheetContent(
state = state,

View file

@ -153,6 +153,7 @@ private fun ChangeOwnRoleBottomSheet(
.navigationBarsPadding(),
sheetState = sheetState,
onDismissRequest = ::dismiss,
scrollable = true,
) {
Text(
modifier = Modifier.padding(14.dp),

View file

@ -17,6 +17,8 @@ import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -224,9 +226,12 @@ private fun RoomMemberActionsBottomSheet(
onDismiss()
}
},
scrollable = false,
) {
Column(
modifier = Modifier.padding(vertical = 16.dp)
modifier = Modifier
.padding(vertical = 16.dp)
.verticalScroll(rememberScrollState())
) {
Avatar(
avatarData = user.getAvatarData(size = AvatarSize.RoomListManageUser),

View file

@ -13,8 +13,10 @@ 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.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -52,11 +54,13 @@ fun JoinRoomByAddressView(
onDismissRequest = {
state.eventSink(JoinRoomByAddressEvent.Dismiss)
},
scrollable = false,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(all = 16.dp),
.padding(all = 16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
RoomAddressField(

View file

@ -14,6 +14,8 @@ 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.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@ -38,11 +40,13 @@ fun SimpleModalBottomSheet(
onDismissRequest = onDismiss,
modifier = modifier,
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
scrollable = false,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
.padding(16.dp)
.verticalScroll(rememberScrollState()),
) {
Text(
title,

View file

@ -10,10 +10,13 @@ package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
@ -42,10 +45,15 @@ import io.element.android.libraries.designsystem.preview.sheetStateForPreview
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
/**
* For parameter [scrollable], set it to true if the content of the sheet does not already contain a scrollable component, such as a LazyColumn,
* to avoid nested scroll issues. In this case, the content will be wrapped in a Column with verticalScroll.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ModalBottomSheet(
onDismissRequest: () -> Unit,
scrollable: Boolean,
modifier: Modifier = Modifier,
sheetState: SheetState = rememberModalBottomSheetState(),
shape: Shape = BottomSheetDefaults.ExpandedShape,
@ -79,8 +87,17 @@ fun ModalBottomSheet(
scrimColor = scrimColor,
dragHandle = dragHandle,
contentWindowInsets = contentWindowInsets,
content = content,
)
) {
if (scrollable) {
Column(
modifier = Modifier.verticalScroll(rememberScrollState()),
) {
content()
}
} else {
content()
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@ -91,13 +108,11 @@ fun SheetState.hide(coroutineScope: CoroutineScope, then: suspend () -> Unit) {
}
}
// This preview and its screenshots are blank, see: https://issuetracker.google.com/issues/283843380
@Preview(group = PreviewGroup.BottomSheets)
@Composable
internal fun ModalBottomSheetLightPreview() =
ElementPreviewLight { ContentToPreview() }
// This preview and its screenshots are blank, see: https://issuetracker.google.com/issues/283843380
@Preview(group = PreviewGroup.BottomSheets)
@Composable
internal fun ModalBottomSheetDarkPreview() =
@ -112,6 +127,7 @@ private fun ContentToPreview() {
) {
ModalBottomSheet(
onDismissRequest = {},
scrollable = false,
) {
Text(
text = "Sheet Content",

View file

@ -67,6 +67,7 @@ fun AvatarActionBottomSheet(
},
modifier = modifier,
sheetState = sheetState,
scrollable = false,
) {
AvatarActionBottomSheetContent(
actions = actions,

View file

@ -14,6 +14,8 @@ 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.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
@ -74,11 +76,13 @@ fun CreateDmConfirmationBottomSheet(
modifier = modifier,
onDismissRequest = onDismiss,
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
scrollable = false,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 24.dp, bottom = 16.dp, start = 16.dp, end = 16.dp),
.padding(top = 24.dp, bottom = 16.dp, start = 16.dp, end = 16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
) {
if (isUserIdentityUnknown) {
@ -148,9 +152,11 @@ fun CreateDmConfirmationBottomSheet(
@PreviewsDayNight
@Composable
internal fun CreateDmConfirmationBottomSheetPreview(@PreviewParameter(
CreateDmConfirmationBottomSheetStateProvider::class
) state: CreateDmConfirmationBottomSheetState) = ElementPreview {
internal fun CreateDmConfirmationBottomSheetPreview(
@PreviewParameter(
CreateDmConfirmationBottomSheetStateProvider::class
) state: CreateDmConfirmationBottomSheetState
) = ElementPreview {
CreateDmConfirmationBottomSheet(
matrixUser = state.matrixUser,
isUserIdentityUnknown = state.isUserIdentityUnknown,
@ -166,7 +172,7 @@ data class CreateDmConfirmationBottomSheetState(
class CreateDmConfirmationBottomSheetStateProvider : PreviewParameterProvider<CreateDmConfirmationBottomSheetState> {
override val values = sequenceOf(
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = false),
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = true),
)
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = false),
CreateDmConfirmationBottomSheetState(matrixUser = aMatrixUser(), isUserIdentityUnknown = true),
)
}

View file

@ -59,7 +59,8 @@ fun MediaDeleteConfirmationBottomSheet(
ModalBottomSheet(
modifier = modifier,
onDismissRequest = onDismiss,
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
scrollable = false,
) {
Column(
modifier = Modifier

View file

@ -72,6 +72,7 @@ fun MediaDetailsBottomSheet(
ModalBottomSheet(
modifier = modifier,
onDismissRequest = onDismiss,
scrollable = false,
) {
Column(
modifier = Modifier

View file

@ -12,6 +12,8 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -37,11 +39,13 @@ fun CaptionWarningBottomSheet(
ModalBottomSheet(
modifier = modifier,
onDismissRequest = onDismiss,
scrollable = false,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp),
) {

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6c755a7dcfc2c9f48d449e570a3f1af1cde299fd90ddd4478e9a4c315cf03128
size 23810

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:efa5408c3af0fcd39659b8d30b21ace43be46d2876815ad592f802a7887b5eb9
size 23678

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1fc512e71e168473e0e976be3e3e6cd24b455273257ad0adf970fc2641da43bb
size 25679

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:de71af50bba66a285b5ef44e1a4fe76ce6dc2e094c4c09ddf701deb9a5db898d
size 22025

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:88b3583d55c6855027f13a152a6fc414f6b9e11d65e5b5403463b84fafe38c3f
size 21891

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e64367832735139b68269a8c679b9c6f2b929b906124a0ee93735cbdd9202d6d
size 23826

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:22e3dce5359ba6dd21bd1c17e4421b8341c51809843394c95a3d80db7a235309
size 25774

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:671a0a0ce5571cb460fba789b58ec1e38b63b26ba61c1daeb5cccb986eb424b4
size 24768

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2a58c642983f209f2c4bb01ee0239c11edab299f48129800cbd41fe7a9032ad4
size 26854

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:43837ff4703be9631370b56097bd36006bce98d23f17db629742c957ce945e5a
size 42390

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8b3025b589185d8d276bd3a809d8d94700268be1aec951fd02ff37072cef4998
size 27431

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2d7acb04225299d448edf35ad1f420ceafcabc7759a8f7d94ce11eca70781f79
size 25339

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56b210d5d8dc06de139735ca34f2b5a4e5e7d0db395dc2dbe7b1c9d479d8858d
size 40405

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3ff47c937641549f63948d114510644aad02723a55e752587a1037752a2b3972
size 25966

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a81e2f9d2c3834004b49b925025478b886c065a12dc850f1c42733e457630b97
size 22442

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3348885402696e4b8005740a452384223f60a64c524c32713cfbd9b3041e494
size 22297

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1a54d3171418082d8bdf442bb34c6b149e2707963f88dd7ea7cbff401534fc0
size 23856

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3ea756319eeb2d9ab6ad2425498a7a9902acada24c3ab359f880b5934f2511e5
size 21384

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c75bbb8425fa4b01f9d0d9398d93785f2a149f4abb820dadbfadf17bf4a6673e
size 21077

View file

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:99defb3eb8530142a74c083d4f4ec2e592d465b3d2cf869e1710031ad6a805c9
size 23136