Merge pull request #2265 from element-hq/bma/notificationCount

Iterate on notification count
This commit is contained in:
Benoit Marty 2024-01-23 12:13:23 +01:00 committed by GitHub
commit b95e13be4b
68 changed files with 307 additions and 99 deletions

View file

@ -431,7 +431,6 @@ class InviteListPresenterTests {
avatarUrl = null, avatarUrl = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
unreadNotificationCount = 0,
inviter = RoomMember( inviter = RoomMember(
userId = A_USER_ID, userId = A_USER_ID,
displayName = A_USER_NAME, displayName = A_USER_NAME,
@ -459,7 +458,6 @@ class InviteListPresenterTests {
avatarUrl = null, avatarUrl = null,
isDirect = true, isDirect = true,
lastMessage = null, lastMessage = null,
unreadNotificationCount = 0,
inviter = RoomMember( inviter = RoomMember(
userId = A_USER_ID, userId = A_USER_ID,
displayName = A_USER_NAME, displayName = A_USER_NAME,
@ -484,7 +482,6 @@ class InviteListPresenterTests {
avatarUrl = null, avatarUrl = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
unreadNotificationCount = 0,
) )
) )

View file

@ -55,7 +55,6 @@ private fun aRoomSummary() = RoomSummary.Filled(
avatarUrl = null, avatarUrl = null,
isDirect = false, isDirect = false,
lastMessage = null, lastMessage = null,
unreadNotificationCount = 0,
notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY, notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
) )
) )

View file

@ -73,7 +73,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
return persistentListOf( return persistentListOf(
aRoomListRoomSummary( aRoomListRoomSummary(
name = "Room", name = "Room",
hasUnread = true, numberOfUnreadMessages = 1,
timestamp = "14:18", timestamp = "14:18",
lastMessage = "A very very very very long message which suites on two lines", lastMessage = "A very very very very long message which suites on two lines",
avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem),
@ -81,7 +81,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList<RoomListRoomSummary> {
), ),
aRoomListRoomSummary( aRoomListRoomSummary(
name = "Room#2", name = "Room#2",
hasUnread = false, numberOfUnreadMessages = 0,
timestamp = "14:16", timestamp = "14:16",
lastMessage = "A short message", lastMessage = "A short message",
avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem), avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem),

View file

@ -141,7 +141,7 @@ private fun RowScope.NameAndTimestampRow(room: RoomListRoomSummary) {
Text( Text(
text = room.timestamp ?: "", text = room.timestamp ?: "",
style = ElementTheme.typography.fontBodySmMedium, style = ElementTheme.typography.fontBodySmMedium,
color = if (room.hasUnread) { color = if (room.isTimestampHighlighted) {
ElementTheme.colors.unreadIndicator ElementTheme.colors.unreadIndicator
} else { } else {
MaterialTheme.roomListRoomMessageDate() MaterialTheme.roomListRoomMessageDate()
@ -173,7 +173,23 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
// Video call // Video call
if (room.hasRoomCall) { OnGoingCallIcon(
room.hasRoomCall,
)
// Other indicators
NotificationIcons(
room.userDefinedNotificationMode,
room.numberOfUnreadMessages,
room.numberOfUnreadMentions,
)
}
}
@Composable
private fun OnGoingCallIcon(
hasRoomCall: Boolean,
) {
if (hasRoomCall) {
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
imageVector = CompoundIcons.VideoCallSolid, imageVector = CompoundIcons.VideoCallSolid,
@ -181,32 +197,53 @@ private fun RowScope.LastMessageAndIndicatorRow(room: RoomListRoomSummary) {
tint = ElementTheme.colors.unreadIndicator, tint = ElementTheme.colors.unreadIndicator,
) )
} }
NotificationIcon(room)
if (room.hasUnread) {
UnreadIndicatorAtom()
}
}
} }
@Composable @Composable
private fun NotificationIcon(room: RoomListRoomSummary) { private fun RowScope.NotificationIcons(
val tint = if (room.hasUnread) ElementTheme.colors.unreadIndicator else ElementTheme.colors.iconQuaternary userDefinedNotificationMode: RoomNotificationMode?,
when (room.userDefinedNotificationMode) { numberOfUnreadMessages: Int,
null, RoomNotificationMode.ALL_MESSAGES -> return numberOfUnreadMentions: Int,
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> ) {
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> {
if (numberOfUnreadMentions > 0) {
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
contentDescription = null, contentDescription = null,
imageVector = CompoundIcons.Mention, imageVector = CompoundIcons.Mention,
tint = tint, tint = ElementTheme.colors.unreadIndicator,
) )
RoomNotificationMode.MUTE -> UnreadIndicatorAtom()
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom()
}
}
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> {
if (numberOfUnreadMentions > 0) {
Icon(
modifier = Modifier.size(16.dp),
contentDescription = null,
imageVector = CompoundIcons.Mention,
tint = ElementTheme.colors.unreadIndicator,
)
UnreadIndicatorAtom()
} else if (numberOfUnreadMessages > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
RoomNotificationMode.MUTE -> {
Icon( Icon(
modifier = Modifier.size(16.dp), modifier = Modifier.size(16.dp),
contentDescription = null, contentDescription = null,
imageVector = CompoundIcons.NotificationsSolidOff, imageVector = CompoundIcons.NotificationsSolidOff,
tint = tint, tint = ElementTheme.colors.iconQuaternary,
) )
if (numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0) {
UnreadIndicatorAtom(color = ElementTheme.colors.iconQuaternary)
}
}
} }
} }

View file

@ -41,7 +41,8 @@ class RoomListRoomSummaryFactory @Inject constructor(
timestamp = "hh:mm", timestamp = "hh:mm",
lastMessage = "Last message for placeholder", lastMessage = "Last message for placeholder",
avatarData = AvatarData(id, "S", size = AvatarSize.RoomListItem), avatarData = AvatarData(id, "S", size = AvatarSize.RoomListItem),
hasUnread = false, numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
userDefinedNotificationMode = null, userDefinedNotificationMode = null,
hasRoomCall = false, hasRoomCall = false,
isDm = false, isDm = false,
@ -66,7 +67,8 @@ class RoomListRoomSummaryFactory @Inject constructor(
id = roomIdentifier, id = roomIdentifier,
roomId = RoomId(roomIdentifier), roomId = RoomId(roomIdentifier),
name = roomSummary.details.name, name = roomSummary.details.name,
hasUnread = roomSummary.details.unreadNotificationCount > 0, numberOfUnreadMessages = roomSummary.details.numUnreadMessages,
numberOfUnreadMentions = roomSummary.details.numUnreadMentions,
timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp), timestamp = lastMessageTimestampFormatter.format(roomSummary.details.lastMessageTimestamp),
lastMessage = roomSummary.details.lastMessage?.let { message -> lastMessage = roomSummary.details.lastMessage?.let { message ->
roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect) roomLastMessageFormatter.format(message.event, roomSummary.details.isDirect)

View file

@ -26,7 +26,8 @@ data class RoomListRoomSummary(
val id: String, val id: String,
val roomId: RoomId, val roomId: RoomId,
val name: String, val name: String,
val hasUnread: Boolean, val numberOfUnreadMessages: Int,
val numberOfUnreadMentions: Int,
val timestamp: String?, val timestamp: String?,
val lastMessage: CharSequence?, val lastMessage: CharSequence?,
val avatarData: AvatarData, val avatarData: AvatarData,
@ -34,4 +35,12 @@ data class RoomListRoomSummary(
val userDefinedNotificationMode: RoomNotificationMode?, val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean, val hasRoomCall: Boolean,
val isDm: Boolean, val isDm: Boolean,
) ) {
val isTimestampHighlighted = hasRoomCall ||
when (userDefinedNotificationMode) {
null,
RoomNotificationMode.ALL_MESSAGES -> numberOfUnreadMessages > 0 || numberOfUnreadMentions > 0
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY -> numberOfUnreadMentions > 0
RoomNotificationMode.MUTE -> false
}
}

View file

@ -25,29 +25,69 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSummary> { open class RoomListRoomSummaryProvider : PreviewParameterProvider<RoomListRoomSummary> {
override val values: Sequence<RoomListRoomSummary> override val values: Sequence<RoomListRoomSummary>
get() = sequenceOf( get() = sequenceOf(
listOf(
aRoomListRoomSummary(isPlaceholder = true),
aRoomListRoomSummary(), aRoomListRoomSummary(),
aRoomListRoomSummary(lastMessage = null), aRoomListRoomSummary(lastMessage = null),
aRoomListRoomSummary(hasUnread = true, notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary(notificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY),
aRoomListRoomSummary(notificationMode = RoomNotificationMode.MUTE),
aRoomListRoomSummary(hasUnread = true),
aRoomListRoomSummary(isPlaceholder = true),
aRoomListRoomSummary( aRoomListRoomSummary(
name = "A very long room name that should be truncated", name = "A very long room name that should be truncated",
lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" + lastMessage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt" +
" ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" + " ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea com" +
"modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", "modo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
timestamp = "yesterday", timestamp = "yesterday",
hasUnread = true, numberOfUnreadMessages = 1,
),
),
listOf(false, true).map { hasCall ->
listOf(
RoomNotificationMode.ALL_MESSAGES,
RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
RoomNotificationMode.MUTE,
).map { roomNotificationMode ->
listOf(
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "No activity" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 0,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 0,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New messages, mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 1,
numberOfUnreadMentions = 1,
hasRoomCall = hasCall,
),
aRoomListRoomSummary(
name = roomNotificationMode.name,
lastMessage = "New mentions" + if (hasCall) ", call" else "",
notificationMode = roomNotificationMode,
numberOfUnreadMessages = 0,
numberOfUnreadMentions = 1,
hasRoomCall = hasCall,
), ),
aRoomListRoomSummary(hasUnread = true, hasRoomCall = true),
) )
}.flatten()
}.flatten(),
).flatten()
} }
internal fun aRoomListRoomSummary( internal fun aRoomListRoomSummary(
id: String = "!roomId:domain", id: String = "!roomId:domain",
name: String = "Room name", name: String = "Room name",
hasUnread: Boolean = false, numberOfUnreadMessages: Int = 0,
numberOfUnreadMentions: Int = 0,
lastMessage: String? = "Last message", lastMessage: String? = "Last message",
timestamp: String? = lastMessage?.let { "88:88" }, timestamp: String? = lastMessage?.let { "88:88" },
isPlaceholder: Boolean = false, isPlaceholder: Boolean = false,
@ -59,7 +99,8 @@ internal fun aRoomListRoomSummary(
id = id, id = id,
roomId = RoomId(id), roomId = RoomId(id),
name = name, name = name,
hasUnread = hasUnread, numberOfUnreadMessages = numberOfUnreadMessages,
numberOfUnreadMentions = numberOfUnreadMentions,
timestamp = timestamp, timestamp = timestamp,
lastMessage = lastMessage, lastMessage = lastMessage,
avatarData = avatarData, avatarData = avatarData,

View file

@ -440,7 +440,8 @@ private val aRoomListRoomSummary = RoomListRoomSummary(
id = A_ROOM_ID.value, id = A_ROOM_ID.value,
roomId = A_ROOM_ID, roomId = A_ROOM_ID,
name = A_ROOM_NAME, name = A_ROOM_NAME,
hasUnread = true, numberOfUnreadMentions = 1,
numberOfUnreadMessages = 2,
timestamp = A_FORMATTED_DATE, timestamp = A_FORMATTED_DATE,
lastMessage = "", lastMessage = "",
avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem), avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem),

View file

@ -40,7 +40,8 @@ data class RoomSummaryDetails(
val isDirect: Boolean, val isDirect: Boolean,
val avatarUrl: String?, val avatarUrl: String?,
val lastMessage: RoomMessage?, val lastMessage: RoomMessage?,
val unreadNotificationCount: Int, val numUnreadMessages: Int,
val numUnreadMentions: Int,
val inviter: RoomMember?, val inviter: RoomMember?,
val userDefinedNotificationMode: RoomNotificationMode?, val userDefinedNotificationMode: RoomNotificationMode?,
val hasRoomCall: Boolean, val hasRoomCall: Boolean,

View file

@ -35,7 +35,8 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto
canonicalAlias = roomInfo.canonicalAlias, canonicalAlias = roomInfo.canonicalAlias,
isDirect = roomInfo.isDirect, isDirect = roomInfo.isDirect,
avatarUrl = roomInfo.avatarUrl, avatarUrl = roomInfo.avatarUrl,
unreadNotificationCount = roomInfo.notificationCount.toInt(), numUnreadMentions = roomInfo.numUnreadMentions.toInt(),
numUnreadMessages = roomInfo.numUnreadMessages.toInt(),
lastMessage = latestRoomMessage, lastMessage = latestRoomMessage,
inviter = roomInfo.inviter?.let(RoomMemberMapper::map), inviter = roomInfo.inviter?.let(RoomMemberMapper::map),
userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode), userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode),

View file

@ -37,7 +37,8 @@ fun aRoomSummaryFilled(
isDirect: Boolean = false, isDirect: Boolean = false,
avatarUrl: String? = null, avatarUrl: String? = null,
lastMessage: RoomMessage? = aRoomMessage(), lastMessage: RoomMessage? = aRoomMessage(),
unreadNotificationCount: Int = 2, numUnreadMentions: Int = 1,
numUnreadMessages: Int = 2,
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
) = RoomSummary.Filled( ) = RoomSummary.Filled(
aRoomSummaryDetails( aRoomSummaryDetails(
@ -46,7 +47,8 @@ fun aRoomSummaryFilled(
isDirect = isDirect, isDirect = isDirect,
avatarUrl = avatarUrl, avatarUrl = avatarUrl,
lastMessage = lastMessage, lastMessage = lastMessage,
unreadNotificationCount = unreadNotificationCount, numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
notificationMode = notificationMode, notificationMode = notificationMode,
) )
) )
@ -57,7 +59,8 @@ fun aRoomSummaryDetails(
isDirect: Boolean = false, isDirect: Boolean = false,
avatarUrl: String? = null, avatarUrl: String? = null,
lastMessage: RoomMessage? = aRoomMessage(), lastMessage: RoomMessage? = aRoomMessage(),
unreadNotificationCount: Int = 2, numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
inviter: RoomMember? = null, inviter: RoomMember? = null,
canonicalAlias: String? = null, canonicalAlias: String? = null,
@ -69,7 +72,8 @@ fun aRoomSummaryDetails(
isDirect = isDirect, isDirect = isDirect,
avatarUrl = avatarUrl, avatarUrl = avatarUrl,
lastMessage = lastMessage, lastMessage = lastMessage,
unreadNotificationCount = unreadNotificationCount, numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
userDefinedNotificationMode = notificationMode, userDefinedNotificationMode = notificationMode,
inviter = inviter, inviter = inviter,
canonicalAlias = canonicalAlias, canonicalAlias = canonicalAlias,

View file

@ -113,7 +113,8 @@ fun aRoomSummaryDetails(
notificationMode: RoomNotificationMode? = null, notificationMode: RoomNotificationMode? = null,
hasRoomCall: Boolean = false, hasRoomCall: Boolean = false,
isDm: Boolean = false, isDm: Boolean = false,
unreadNotificationCount: Int = 0 numUnreadMentions: Int = 0,
numUnreadMessages: Int = 0,
) = RoomSummaryDetails( ) = RoomSummaryDetails(
roomId = roomId, roomId = roomId,
name = name, name = name,
@ -125,5 +126,6 @@ fun aRoomSummaryDetails(
userDefinedNotificationMode = notificationMode, userDefinedNotificationMode = notificationMode,
hasRoomCall = hasRoomCall, hasRoomCall = hasRoomCall,
isDm = isDm, isDm = isDm,
unreadNotificationCount = unreadNotificationCount, numUnreadMentions = numUnreadMentions,
numUnreadMessages = numUnreadMessages,
) )

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:57e0c90fa627974aba0d62363906bcc7911a6ada7d9d7db00db0df1d51fed54c oid sha256:c978bc799ab79290f89568de692d3ace219a4192ec9706fef63fe977a853f74d
size 12911 size 6046

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:fcf2f25bbcb2f43d70a8a3228ba97426dbb98b533b74dd13ef6459f96a711db5 oid sha256:57e0c90fa627974aba0d62363906bcc7911a6ada7d9d7db00db0df1d51fed54c
size 8877 size 12911

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d1d8c374c7c3f8ad66b3936e8eda3161a93281aa3107027516ab671958f10980 oid sha256:fcf2f25bbcb2f43d70a8a3228ba97426dbb98b533b74dd13ef6459f96a711db5
size 14187 size 8877

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:352b75021319958e86affa3d44c38cf72151d32796d70a0920ef63d73984ad72 oid sha256:a1dfe518ad4ee77539f017a39c684e0ce7bfb733a33161639fdf606a188b13d0
size 13627 size 22406

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:14e33bc8286952b7608adfa9864a1649c817992d35e9e0de8edc9957b8f4a6c6 oid sha256:d5e32fab6c9f6500bf523a18d10464a7b703649c80e6f1c56bc124cadbd2d248
size 13388 size 13512

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d8442308cab3c75f64559bcd67dc39ce6d95a546ae33a7eb885c775349ab36f5 oid sha256:176f15fb96c05d5932708c9eb26a98261540f07fa4204a416b67baa2388993e5
size 13378 size 14775

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:c978bc799ab79290f89568de692d3ace219a4192ec9706fef63fe977a853f74d oid sha256:275649c8aceae86b0ab6ef633dc3bb9533d443a1ab3125fc16d8a288cdd8e8dc
size 6046 size 16937

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:a1dfe518ad4ee77539f017a39c684e0ce7bfb733a33161639fdf606a188b13d0 oid sha256:72aa257540b31b448e5eb57610c0d62422bc1d40c2abbdb41da99d6244a316c3
size 22406 size 15172

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:b044aa278ad070f75ffcf3d0d895c93bd784eb9c3e19e6aa842bbc1170bc92b4 oid sha256:eaa409bac7f41b101207542e7be42b3caacd3039f6918dd1bb1df3105dffa1e0
size 13688 size 15747

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:1d914ad609cda9e94ba793027c17f3b7289fec71e65e1880b837615203f7718e oid sha256:144decfd898287f548035c89c264eb5f380084bfe69328a115b8c42cda5282f7
size 12907 size 5963

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:e05f294579b4420e6671f268d10fae8fb49e93e5ae5b0f0d4548f7cdfeb82742 oid sha256:1d914ad609cda9e94ba793027c17f3b7289fec71e65e1880b837615203f7718e
size 8928 size 12907

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:4fcbb393a93d6a04e0415d2bb7bed4c002ec82907fbccf6070a4880a6b208e3c oid sha256:e05f294579b4420e6671f268d10fae8fb49e93e5ae5b0f0d4548f7cdfeb82742
size 13942 size 8928

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:811d95287c12d59fa1014b62ac8ae755f6355dbbd0700c2adc331293adfcc7a4 oid sha256:b5f274b1ad4ca31aaf585d34ce48c2898fbb9ada8294b211fe1440a097da21f6
size 13535 size 21626

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:435737296b59d70210fc93ba70d2fa228ba4bab645fb9a6366609197a97f87c0 oid sha256:ca84726aa42db2d961b328d3ba34523f783f215fed36d049da1cf8a503d0dca7
size 13305 size 13304

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d5a2d15ec2b36255963bc2514df0ff2dc8588c177d06c5431ca457af4de916e6 oid sha256:9e13796d33e2ae08bdf7e1b9cc3ae4216e4a4d86054b8172d7054f8758232f03
size 13210 size 14406

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:144decfd898287f548035c89c264eb5f380084bfe69328a115b8c42cda5282f7 oid sha256:f5b24a09682a6e23f9fb5ae95bf61a76b2ac711dcb6e61485a3a0de0766062f9
size 5963 size 16423

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:b5f274b1ad4ca31aaf585d34ce48c2898fbb9ada8294b211fe1440a097da21f6 oid sha256:a839e11d5f481cdc3973ee1a863badf44df39cd3c20571e9e475800bff726913
size 21626 size 14714

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:a13837fffa77d7f95d6f4f163fb2e674070777caf02cce74b6a52e91f3103224 oid sha256:0ff91c8812358efc55693fb855aa1c7bb5f617ebbf6fad7f57ab5cbe3b8a6123
size 13500 size 15323

View file

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