Merge pull request #4056 from element-hq/feature/bma/messageActionList

Update message action list
This commit is contained in:
Benoit Marty 2024-12-18 16:47:51 +01:00 committed by GitHub
commit 0648cf36f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 150 additions and 157 deletions

View file

@ -274,7 +274,8 @@ class MessagesPresenter @AssistedInject constructor(
TimelineItemAction.CopyCaption -> handleCopyCaption(targetEvent)
TimelineItemAction.CopyLink -> handleCopyLink(targetEvent)
TimelineItemAction.Redact -> handleActionRedact(targetEvent)
TimelineItemAction.Edit -> handleActionEdit(targetEvent, composerState, enableTextFormatting)
TimelineItemAction.Edit,
TimelineItemAction.EditPoll -> handleActionEdit(targetEvent, composerState, enableTextFormatting)
TimelineItemAction.AddCaption -> handleActionAddCaption(targetEvent, composerState)
TimelineItemAction.EditCaption -> handleActionEditCaption(targetEvent, composerState)
TimelineItemAction.RemoveCaption -> handleRemoveCaption(targetEvent)

View file

@ -178,6 +178,8 @@ class DefaultActionListPresenter @AssistedInject constructor(
add(TimelineItemAction.EditCaption)
add(TimelineItemAction.RemoveCaption)
}
} else if (timelineItem.content is TimelineItemPollContent) {
add(TimelineItemAction.EditPoll)
} else {
add(TimelineItemAction.Edit)
}

View file

@ -203,6 +203,7 @@ fun aTimelineItemActionList(
fun aTimelineItemPollActionList(): ImmutableList<TimelineItemAction> {
return setOf(
TimelineItemAction.EndPoll,
TimelineItemAction.EditPoll,
TimelineItemAction.Reply,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,

View file

@ -11,30 +11,30 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.runtime.Immutable
import io.element.android.libraries.designsystem.icons.CompoundDrawables
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.ui.strings.CommonStrings
@Immutable
sealed class TimelineItemAction(
enum class TimelineItemAction(
@StringRes val titleRes: Int,
@DrawableRes val icon: Int,
val destructive: Boolean = false
) {
data object ViewInTimeline : TimelineItemAction(CommonStrings.action_view_in_timeline, CompoundDrawables.ic_compound_visibility_on)
data object Forward : TimelineItemAction(CommonStrings.action_forward, CompoundDrawables.ic_compound_forward)
data object CopyText : TimelineItemAction(CommonStrings.action_copy_text, CompoundDrawables.ic_compound_copy)
data object CopyCaption : TimelineItemAction(CommonStrings.action_copy_caption, CompoundDrawables.ic_compound_copy)
data object CopyLink : TimelineItemAction(CommonStrings.action_copy_link_to_message, CompoundDrawables.ic_compound_link)
data object Redact : TimelineItemAction(CommonStrings.action_remove, CompoundDrawables.ic_compound_delete, destructive = true)
data object Reply : TimelineItemAction(CommonStrings.action_reply, CompoundDrawables.ic_compound_reply)
data object ReplyInThread : TimelineItemAction(CommonStrings.action_reply_in_thread, CompoundDrawables.ic_compound_reply)
data object Edit : TimelineItemAction(CommonStrings.action_edit, CompoundDrawables.ic_compound_edit)
data object EditCaption : TimelineItemAction(CommonStrings.action_edit_caption, CompoundDrawables.ic_compound_edit)
data object AddCaption : TimelineItemAction(CommonStrings.action_add_caption, CompoundDrawables.ic_compound_edit)
data object RemoveCaption : TimelineItemAction(CommonStrings.action_remove_caption, CompoundDrawables.ic_compound_delete, destructive = true)
data object ViewSource : TimelineItemAction(CommonStrings.action_view_source, CommonDrawables.ic_developer_options)
data object ReportContent : TimelineItemAction(CommonStrings.action_report_content, CompoundDrawables.ic_compound_chat_problem, destructive = true)
data object EndPoll : TimelineItemAction(CommonStrings.action_end_poll, CompoundDrawables.ic_compound_polls_end)
data object Pin : TimelineItemAction(CommonStrings.action_pin, CompoundDrawables.ic_compound_pin)
data object Unpin : TimelineItemAction(CommonStrings.action_unpin, CompoundDrawables.ic_compound_unpin)
ViewInTimeline(CommonStrings.action_view_in_timeline, CompoundDrawables.ic_compound_visibility_on),
Forward(CommonStrings.action_forward, CompoundDrawables.ic_compound_forward),
CopyText(CommonStrings.action_copy_text, CompoundDrawables.ic_compound_copy),
CopyCaption(CommonStrings.action_copy_caption, CompoundDrawables.ic_compound_copy),
CopyLink(CommonStrings.action_copy_link_to_message, CompoundDrawables.ic_compound_link),
Redact(CommonStrings.action_remove, CompoundDrawables.ic_compound_delete, destructive = true),
Reply(CommonStrings.action_reply, CompoundDrawables.ic_compound_reply),
ReplyInThread(CommonStrings.action_reply_in_thread, CompoundDrawables.ic_compound_reply),
Edit(CommonStrings.action_edit, CompoundDrawables.ic_compound_edit),
EditPoll(CommonStrings.action_edit_poll, CompoundDrawables.ic_compound_edit),
EditCaption(CommonStrings.action_edit_caption, CompoundDrawables.ic_compound_edit),
AddCaption(CommonStrings.action_add_caption, CompoundDrawables.ic_compound_edit),
RemoveCaption(CommonStrings.action_remove_caption, CompoundDrawables.ic_compound_close, destructive = true),
ViewSource(CommonStrings.action_view_source, CompoundDrawables.ic_compound_code),
ReportContent(CommonStrings.action_report_content, CompoundDrawables.ic_compound_chat_problem, destructive = true),
EndPoll(CommonStrings.action_end_poll, CompoundDrawables.ic_compound_polls_end),
Pin(CommonStrings.action_pin, CompoundDrawables.ic_compound_pin),
Unpin(CommonStrings.action_unpin, CompoundDrawables.ic_compound_unpin),
}

View file

@ -7,21 +7,25 @@
package io.element.android.features.messages.impl.actionlist.model
import androidx.annotation.VisibleForTesting
class TimelineItemActionComparator : Comparator<TimelineItemAction> {
// See order in https://www.figma.com/design/ux3tYoZV9WghC7hHT9Fhk0/Compound-iOS-Components?node-id=2946-2392
private val orderedList = listOf(
@VisibleForTesting
val orderedList = listOf(
TimelineItemAction.EndPoll,
TimelineItemAction.ViewInTimeline,
TimelineItemAction.Reply,
TimelineItemAction.ReplyInThread,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.Unpin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyText,
TimelineItemAction.EditPoll,
TimelineItemAction.AddCaption,
TimelineItemAction.EditCaption,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.Unpin,
TimelineItemAction.CopyText,
TimelineItemAction.CopyCaption,
TimelineItemAction.RemoveCaption,
TimelineItemAction.ViewSource,

View file

@ -14,9 +14,9 @@ class PinnedMessagesListTimelineActionPostProcessor : TimelineItemActionPostProc
override fun process(actions: List<TimelineItemAction>): List<TimelineItemAction> {
return buildList {
add(TimelineItemAction.ViewInTimeline)
actions.firstOrNull { it is TimelineItemAction.Unpin }?.let(::add)
actions.firstOrNull { it is TimelineItemAction.Forward }?.let(::add)
actions.firstOrNull { it is TimelineItemAction.ViewSource }?.let(::add)
actions.firstOrNull { it == TimelineItemAction.Unpin }?.let(::add)
actions.firstOrNull { it == TimelineItemAction.Forward }?.let(::add)
actions.firstOrNull { it == TimelineItemAction.ViewSource }?.let(::add)
}
}
}

View file

@ -467,7 +467,7 @@ class MessagesPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent(content = aTimelineItemPollContent())))
initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EditPoll, aMessageEvent(content = aTimelineItemPollContent())))
awaitItem()
onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID))
}

View file

@ -179,8 +179,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -225,8 +225,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.ReplyInThread,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -273,8 +273,8 @@ class ActionListPresenterTest {
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = persistentListOf(
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -320,8 +320,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -368,8 +368,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -417,9 +417,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
@ -463,9 +463,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.ReplyInThread,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
@ -512,9 +512,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
)
@ -559,9 +559,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.AddCaption,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
)
@ -612,8 +612,8 @@ class ActionListPresenterTest {
TimelineItemAction.Forward,
// Not here
// TimelineItemAction.AddCaption,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
)
@ -660,9 +660,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.EditCaption,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyCaption,
TimelineItemAction.RemoveCaption,
TimelineItemAction.ViewSource,
@ -711,8 +711,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyCaption,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
@ -830,9 +830,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.CopyText,
TimelineItemAction.Redact,
)
@ -878,8 +878,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
@ -933,9 +933,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Unpin,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.CopyLink,
TimelineItemAction.Unpin,
TimelineItemAction.CopyText,
TimelineItemAction.ViewSource,
TimelineItemAction.Redact,
@ -1072,9 +1072,9 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.EndPoll,
TimelineItemAction.Reply,
TimelineItemAction.Pin,
TimelineItemAction.EditPoll,
TimelineItemAction.CopyLink,
TimelineItemAction.Edit,
TimelineItemAction.Pin,
TimelineItemAction.Redact,
)
)
@ -1116,8 +1116,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.EndPoll,
TimelineItemAction.Reply,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.Redact,
)
)
@ -1158,8 +1158,8 @@ class ActionListPresenterTest {
verifiedUserSendFailure = VerifiedUserSendFailure.None,
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.Redact,
)
)
@ -1203,8 +1203,8 @@ class ActionListPresenterTest {
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Pin,
TimelineItemAction.CopyLink,
TimelineItemAction.Pin,
TimelineItemAction.Redact,
)
)

View file

@ -0,0 +1,28 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only
* Please see LICENSE in the repository root for full details.
*/
package io.element.android.features.messages.impl.actionlist.model
import org.junit.Test
class TimelineItemActionComparatorTest {
@Test
fun `check that the list in the comparator only contain each item once`() {
val sut = TimelineItemActionComparator()
sut.orderedList.forEach {
require(sut.orderedList.count { item -> item == it } == 1, { "Duplicate ${it::class.java}.$it" })
}
}
@Test
fun `check that the list in the comparator contains all the items`() {
val sut = TimelineItemActionComparator()
TimelineItemAction.entries.forEach {
require(it in sut.orderedList, { "Missing ${it::class.simpleName}.$it in orderedList" })
}
}
}

View file

@ -27,24 +27,7 @@ class PinnedMessagesListTimelineActionPostProcessorTest {
fun `ensure that some actions are kept and some other are filtered out`() {
val sut = PinnedMessagesListTimelineActionPostProcessor()
val result = sut.process(
listOf(
TimelineItemAction.Forward,
TimelineItemAction.CopyText,
TimelineItemAction.CopyCaption,
TimelineItemAction.CopyLink,
TimelineItemAction.Redact,
TimelineItemAction.Reply,
TimelineItemAction.ReplyInThread,
TimelineItemAction.Edit,
TimelineItemAction.EditCaption,
TimelineItemAction.AddCaption,
TimelineItemAction.RemoveCaption,
TimelineItemAction.ViewSource,
TimelineItemAction.ReportContent,
TimelineItemAction.EndPoll,
TimelineItemAction.Pin,
TimelineItemAction.Unpin,
)
TimelineItemAction.entries.toList()
)
assertThat(result).isEqualTo(
listOf(

View file

@ -25,6 +25,7 @@ import io.element.android.features.preferences.impl.user.UserPreferences
import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage
import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
import io.element.android.libraries.designsystem.icons.CompoundDrawables
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewWithLargeHeight
@ -33,7 +34,6 @@ import io.element.android.libraries.designsystem.theme.components.IconSource
import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.ListItemStyle
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.CommonDrawables
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost
import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.core.DeviceId
@ -270,7 +270,7 @@ private fun ColumnScope.Footer(
private fun DeveloperPreferencesView(onOpenDeveloperSettings: () -> Unit) {
ListItem(
headlineContent = { Text(stringResource(id = CommonStrings.common_developer_options)) },
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_developer_options)),
leadingContent = ListItemContent.Icon(IconSource.Resource(CompoundDrawables.ic_compound_code)),
onClick = onOpenDeveloperSettings
)
}

View file

@ -13,9 +13,7 @@ import io.element.android.libraries.designsystem.R
// All the icons should be defined in Compound.
internal val iconsOther = listOf(
R.drawable.ic_cancel,
R.drawable.ic_developer_options,
R.drawable.ic_encryption_enabled,
R.drawable.ic_groups,
R.drawable.ic_notification_small,
R.drawable.ic_plus_composer,
R.drawable.ic_stop,

View file

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M8.825,12L10.3,10.525C10.5,10.325 10.6,10.092 10.6,9.825C10.6,9.558 10.5,9.325 10.3,9.125C10.1,8.925 9.863,8.825 9.587,8.825C9.313,8.825 9.075,8.925 8.875,9.125L6.7,11.3C6.6,11.4 6.529,11.508 6.488,11.625C6.446,11.742 6.425,11.867 6.425,12C6.425,12.133 6.446,12.258 6.488,12.375C6.529,12.492 6.6,12.6 6.7,12.7L8.875,14.875C9.075,15.075 9.313,15.175 9.587,15.175C9.863,15.175 10.1,15.075 10.3,14.875C10.5,14.675 10.6,14.442 10.6,14.175C10.6,13.908 10.5,13.675 10.3,13.475L8.825,12ZM15.175,12L13.7,13.475C13.5,13.675 13.4,13.908 13.4,14.175C13.4,14.442 13.5,14.675 13.7,14.875C13.9,15.075 14.137,15.175 14.413,15.175C14.688,15.175 14.925,15.075 15.125,14.875L17.3,12.7C17.4,12.6 17.471,12.492 17.513,12.375C17.554,12.258 17.575,12.133 17.575,12C17.575,11.867 17.554,11.742 17.513,11.625C17.471,11.508 17.4,11.4 17.3,11.3L15.125,9.125C15.025,9.025 14.913,8.95 14.788,8.9C14.663,8.85 14.538,8.825 14.413,8.825C14.288,8.825 14.163,8.85 14.038,8.9C13.913,8.95 13.8,9.025 13.7,9.125C13.5,9.325 13.4,9.558 13.4,9.825C13.4,10.092 13.5,10.325 13.7,10.525L15.175,12ZM5,21C4.45,21 3.979,20.804 3.588,20.413C3.196,20.021 3,19.55 3,19V5C3,4.45 3.196,3.979 3.588,3.588C3.979,3.196 4.45,3 5,3H19C19.55,3 20.021,3.196 20.413,3.588C20.804,3.979 21,4.45 21,5V19C21,19.55 20.804,20.021 20.413,20.413C20.021,20.804 19.55,21 19,21H5ZM5,19H19V5H5V19Z"
android:fillColor="#1B1D22"/>
</vector>

View file

@ -1,15 +0,0 @@
<!--
~ Copyright 2023 New Vector Ltd.
~
~ SPDX-License-Identifier: AGPL-3.0-only
~ Please see LICENSE in the repository root for full details.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M1.365,17.788C1.12,17.788 0.915,17.705 0.749,17.54C0.583,17.374 0.5,17.168 0.5,16.923V16.569C0.5,15.894 0.844,15.346 1.531,14.927C2.219,14.508 3.126,14.298 4.251,14.298C4.454,14.298 4.647,14.305 4.829,14.318C5.011,14.332 5.187,14.355 5.358,14.389C5.168,14.681 5.028,14.995 4.94,15.332C4.852,15.668 4.808,16.024 4.808,16.4V17.788H1.365ZM7.408,17.788C7.147,17.788 6.931,17.702 6.759,17.529C6.586,17.355 6.5,17.141 6.5,16.885V16.438C6.5,15.483 7.006,14.713 8.018,14.128C9.03,13.543 10.356,13.25 11.996,13.25C13.651,13.25 14.982,13.543 15.989,14.128C16.996,14.713 17.5,15.483 17.5,16.438V16.885C17.5,17.141 17.413,17.355 17.24,17.529C17.067,17.702 16.852,17.788 16.596,17.788H7.408ZM19.192,17.788V16.4C19.192,16.024 19.145,15.668 19.05,15.332C18.955,14.995 18.819,14.681 18.642,14.389C18.813,14.355 18.989,14.332 19.17,14.318C19.352,14.305 19.545,14.298 19.75,14.298C20.875,14.298 21.781,14.508 22.469,14.927C23.156,15.346 23.5,15.894 23.5,16.569V16.923C23.5,17.168 23.417,17.374 23.251,17.54C23.085,17.705 22.88,17.788 22.635,17.788H19.192ZM12,14.75C10.954,14.75 10.059,14.892 9.315,15.176C8.572,15.46 8.159,15.799 8.077,16.192V16.288H15.923V16.192C15.831,15.788 15.415,15.447 14.677,15.168C13.938,14.889 13.046,14.75 12,14.75ZM4.25,13.327C3.777,13.327 3.375,13.159 3.044,12.824C2.713,12.489 2.548,12.086 2.548,11.615C2.548,11.145 2.713,10.742 3.044,10.407C3.375,10.071 3.777,9.904 4.25,9.904C4.723,9.904 5.127,10.071 5.461,10.407C5.794,10.742 5.961,11.145 5.961,11.615C5.961,12.086 5.794,12.489 5.459,12.824C5.124,13.159 4.721,13.327 4.25,13.327ZM19.75,13.327C19.277,13.327 18.873,13.159 18.539,12.824C18.205,12.489 18.038,12.086 18.038,11.615C18.038,11.145 18.206,10.742 18.541,10.407C18.876,10.071 19.279,9.904 19.75,9.904C20.223,9.904 20.625,10.071 20.956,10.407C21.286,10.742 21.452,11.145 21.452,11.615C21.452,12.086 21.286,12.489 20.956,12.824C20.625,13.159 20.223,13.327 19.75,13.327ZM12,12.5C11.279,12.5 10.666,12.248 10.161,11.743C9.656,11.238 9.404,10.625 9.404,9.904C9.404,9.183 9.656,8.57 10.161,8.065C10.666,7.56 11.279,7.308 12,7.308C12.721,7.308 13.334,7.56 13.839,8.065C14.344,8.57 14.596,9.183 14.596,9.904C14.596,10.625 14.344,11.238 13.839,11.743C13.334,12.248 12.721,12.5 12,12.5ZM12.002,8.808C11.691,8.808 11.431,8.913 11.22,9.122C11.009,9.332 10.904,9.592 10.904,9.902C10.904,10.212 11.009,10.473 11.218,10.684C11.428,10.895 11.688,11 11.998,11C12.308,11 12.569,10.895 12.78,10.685C12.991,10.476 13.096,10.216 13.096,9.906C13.096,9.595 12.991,9.335 12.781,9.124C12.572,8.913 12.312,8.808 12.002,8.808Z" />
</vector>

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dbef9e8e887fa493ca9b875e64dc164bf35dd84ad25b84a1ad9b6fd523b26c38
size 27280
oid sha256:4bcf877df431dfe4cf3c7f19d58c413356cdf77ae26f9dfbc9f9136fea3f5c02
size 29361

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c1a0bc9c83b7e01f9492443433781509c0d899b397652fc7e9b7a539d8ce0412
size 48219
oid sha256:88d5893c849bfb7945535f1f450e0c8b8975b5b4eb3ca336bff73aa607f2f34d
size 48171

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3a624587095825c971186288a0ad5a40ddfcadc8f4b9f92b1102d8ae20ca3bda
oid sha256:3f0451276061db5c189062b32414fd93c2f174c3e7597ab723c3f1a0abbfae28
size 49821

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4cdcc38bfae43298654c3e09d7ab1ca1e0d2fd32157a464539a360f3943f4f75
size 42839
oid sha256:f8ec0f80c44ea01158f58e53c0aeafe6df0586e13ff452a61c8b6a9ffb070702
size 42824

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a56b3e488ceecd0bfb763d60b6827f7d8c460fa198d380a502ff0d97b13c9bc0
size 45962
oid sha256:22aabc7669365a40151e7ecd82a3324a53d0f55a370e0dd803d843a5275b1434
size 45949

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:600f28097c6ef8c54fe136d9bb05b8b800d693bff23f238a4e3e0216ee9918ff
size 44404
oid sha256:1a82048429ed60a4b246c37bc1b104e166c8c2402884766a9e487ca98ad45a57
size 44391

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:054cfe9290f91cf0f5d17e8f7c49e71eb50a2bb17067b1edc3c29f89410f76e8
size 40806
oid sha256:b7e8e9782859caf125c6258a612d52532cf005d1d21146e21068882b586f5d1d
size 40788

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:814bb524af65d077e3610e8cb920e5207aa808111a530357e8687831bd9c0413
size 44687
oid sha256:640a1d04239f041ae395b56eee251a2942764c97dc50db3a8d4c3bfc44225a1a
size 44670

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4da93eb0b9fcea861ae80d6e14bc852acaacea52402b1b41e8c982b9c06b2b63
size 42105
oid sha256:150a3d6bd18e87b15575f7f452b222f07e6c3ef227032cbfe84a7728d17c491e
size 42088

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4886407cfe23d5d16aadeef4226698957dad99dfc4d9ac5c184fe64347b3ee41
size 44524
oid sha256:737959115454525aa41c67d3ff47aa1829d78c7d18648b7c14b5e62ff6e44436
size 44511

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3c0d8491dbf0b6f50ae6be5c7aaf0d77b9eaa3a31e7763f120d6e08993c1c74b
size 34028
oid sha256:dd031f67683678815eb3f4b55f3ee65fb79096035705019770a626bfc5c00794
size 34009

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64a6d1a6af14176c933387a7a36de0d7392b1cd31cb04fcc5c6a282317874aac
size 26597
oid sha256:97fbbf4f3b9466a086a8824f9230a1ea5525314d818e19879a2c5340c9495138
size 28642

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f92ebc24de4dd34b84fcbbcc656a369d4a79bca160666c2fd4d32b5516c2f8fb
size 47245
oid sha256:69f31cbb83a84e57e8a9e7bf4ff451d5a192523486c400abdc293a467ca0ffa5
size 47200

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2a4a3730a941a4c6863c116b401ea7e4d5c2cef3fe4098e353954c4f93aa660a
size 48771
oid sha256:410450770889b906c279084668980b41357e432345bc098560d8b06d6e35c86d
size 48841

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:77521de94c04228ca0fb5d09cb7809527cf0dc0acc52a271a8fa4738a752aa66
size 42028
oid sha256:4ce4a7fdb57fd4afae868aa733b013fd5e4daea6aaa736256ed72d9d5eb759e7
size 41988

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:171ef67bdc5a1b6d921ecbdb13e3c79dfab073d7289862181a69515e6063c4c5
size 45246
oid sha256:6721b3503beb8ddfa9efc52a7ab269c6aea9fcefad2c1b1b9ce31b4240d48719
size 45204

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1a8328afeab339104a83db16d7b4b894c060ff7e80c2b5c4d6ec64d3bc4cdc3a
size 43613
oid sha256:ac363ebe575582b39b3ebd7857ff891994f512064f167fee342a9a2b2a35dd1e
size 43572

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d575d08141bf446de510162f5dc1e04fccf4831649495bdf94945bd8957768a6
size 40201
oid sha256:3d30a38861e317010616e7b17614803439f345e376f36b32e3e6e832070ada71
size 40150

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:606379fcb517afa4583ac03fcb2af4f5649a7fc064df841f442c19f5a71f629b
size 43863
oid sha256:96f4023e2a502fb50dc9c03ad53faa932baf1e316652651e109f21f531adb5de
size 43819

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d63dec242ea479beb9a7bf0a58c6f31e2bba84df0a7db51fb07ea46612944d9a
size 41355
oid sha256:8f52f074d2dbf93c3170c80dd18f4601ad1e2db6c57773d0e10c3f8c29ffdc9f
size 41303

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f5421b7b5ce8441213b1323b4cd88c2f5aff6689ecd091b5be581fe5690cd611
size 43685
oid sha256:504ac65ffbcb0705f3e73d32970cd345d23d19e4f190420f8953e55250056329
size 43641

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e1f4600552aebd3a567251a85105a423882942b23e96f7958238a9b5ba0bb8fc
size 33137
oid sha256:f72f6ec83324b0b6e3719e1e0f59387cb0376149decbb780970dcb7f219a1551
size 33053

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:48320aed4570138a76b04b08f37f67098a72e1b63f13273fd6d9c0a6e33b7e10
size 37955
oid sha256:4a6a54efb3bb7eeb97cfa06995a199eb83a7e630fb1b631d7992b464e0b04d20
size 37954

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6a71b634518191f299c924f8ddd39b44ddc1255698e981796bb8b034377c515f
size 37712
oid sha256:d35962150a8dc5b7d774af160a994182afbe2d5538e204b2545c02287897cd99
size 37711

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e33a80d4f6dc4a1bd1cd86b2bfd64471926871f92d8d83cae6b32a79459c8ea0
size 38775
oid sha256:a3711fb587d635b28a398bb5b475bee16d4abdbf691d494348fe11e270e0624d
size 38774

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c69e1d5748e65b35525df64b83c6616ab439299284ab2bda3a8408d5f4139d2f
size 38802
oid sha256:41b91c8a1805bb24453c6f85091704e609a01f83a86ca17979d97de4c20e4cbe
size 38800

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:448e4fea5f9363a84c020548764328e477662aecc7f423237ea06e439563b507
size 25511
oid sha256:560c9159e78e9da940da58a4297aca1ac647218fab0e03c532016ac96a3a560d
size 21524

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c4efddd547921361891b175554e3ae789259f7059fc18b68bcca2a38401f387a
size 24742
oid sha256:b0bb37fb7f6dbce206288431c59e3cc1b31d1a5a25d73b2f2321d7d46a459da5
size 20631