Merge branch 'develop' of github.com:vector-im/element-x-android into develop
This commit is contained in:
commit
0ef4817da3
34 changed files with 250 additions and 115 deletions
1
changelog.d/1064.wip
Normal file
1
changelog.d/1064.wip
Normal file
|
|
@ -0,0 +1 @@
|
|||
[Poll] Add feature flag in developer options
|
||||
|
|
@ -89,7 +89,7 @@ class TimelineItemsFactory @Inject constructor(
|
|||
this.timelineItems.emit(result)
|
||||
}
|
||||
|
||||
private fun buildAndCacheItem(
|
||||
private suspend fun buildAndCacheItem(
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
index: Int
|
||||
): TimelineItem? {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class TimelineItemContentFactory @Inject constructor(
|
|||
private val failedToParseStateFactory: TimelineItemContentFailedToParseStateFactory
|
||||
) {
|
||||
|
||||
fun create(eventTimelineItem: EventTimelineItem): TimelineItemEventContent {
|
||||
suspend fun create(eventTimelineItem: EventTimelineItem): TimelineItemEventContent {
|
||||
return when (val itemContent = eventTimelineItem.content) {
|
||||
is FailedToParseMessageLikeContent -> failedToParseMessageFactory.create(itemContent)
|
||||
is FailedToParseStateContent -> failedToParseStateFactory.create(itemContent)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@ package io.element.android.features.messages.impl.timeline.factories.event
|
|||
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
|
||||
import io.element.android.features.poll.api.PollAnswerItem
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
|
|
@ -26,9 +29,12 @@ import javax.inject.Inject
|
|||
|
||||
class TimelineItemContentPollFactory @Inject constructor(
|
||||
private val matrixClient: MatrixClient,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
) {
|
||||
|
||||
fun create(content: PollContent): TimelineItemEventContent {
|
||||
suspend fun create(content: PollContent): TimelineItemEventContent {
|
||||
if (!featureFlagService.isFeatureEnabled(FeatureFlags.Polls)) return TimelineItemUnknownContent
|
||||
|
||||
// Todo Move this computation to the matrix rust sdk
|
||||
val showResults = content.kind == PollKind.Disclosed && matrixClient.sessionId in content.votes.flatMap { it.value }
|
||||
val pollVotesCount = content.votes.flatMap { it.value }.size
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class TimelineItemEventFactory @Inject constructor(
|
|||
private val matrixClient: MatrixClient,
|
||||
) {
|
||||
|
||||
fun create(
|
||||
suspend fun create(
|
||||
currentTimelineItem: MatrixTimelineItem.Event,
|
||||
index: Int,
|
||||
timelineItems: List<MatrixTimelineItem>,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import io.element.android.features.messages.impl.timeline.util.FileExtensionExtr
|
|||
import io.element.android.libraries.androidutils.filesize.FakeFileSizeFormatter
|
||||
import io.element.android.libraries.dateformatter.test.FakeDaySeparatorFormatter
|
||||
import io.element.android.libraries.eventformatter.api.TimelineEventFormatter
|
||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
|
|
@ -52,14 +53,14 @@ internal fun TestScope.aTimelineItemsFactory(): TimelineItemsFactory {
|
|||
messageFactory = TimelineItemContentMessageFactory(FakeFileSizeFormatter(), FileExtensionExtractorWithoutValidation()),
|
||||
redactedMessageFactory = TimelineItemContentRedactedFactory(),
|
||||
stickerFactory = TimelineItemContentStickerFactory(),
|
||||
pollFactory = TimelineItemContentPollFactory(matrixClient),
|
||||
pollFactory = TimelineItemContentPollFactory(matrixClient, FakeFeatureFlagService()),
|
||||
pollEndFactory = TimelineItemContentPollEndFactory(),
|
||||
utdFactory = TimelineItemContentUTDFactory(),
|
||||
roomMembershipFactory = TimelineItemContentRoomMembershipFactory(timelineEventFormatter),
|
||||
profileChangeFactory = TimelineItemContentProfileChangeFactory(timelineEventFormatter),
|
||||
stateFactory = TimelineItemContentStateFactory(timelineEventFormatter),
|
||||
failedToParseMessageFactory = TimelineItemContentFailedToParseMessageFactory(),
|
||||
failedToParseStateFactory = TimelineItemContentFailedToParseStateFactory()
|
||||
failedToParseStateFactory = TimelineItemContentFailedToParseStateFactory(),
|
||||
),
|
||||
matrixClient = matrixClient,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class DeveloperSettingsPresenter @Inject constructor(
|
|||
FeatureUiModel(
|
||||
key = feature.key,
|
||||
title = feature.title,
|
||||
description = feature.description,
|
||||
isEnabled = isEnabled
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package io.element.android.libraries.designsystem.atomic.atoms
|
||||
|
||||
import android.graphics.BlurMaskFilter
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
|
|
@ -27,24 +26,16 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.blur
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.geometry.CornerRadius
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.geometry.RoundRect
|
||||
import androidx.compose.ui.graphics.ClipOp
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Paint
|
||||
import androidx.compose.ui.graphics.Path
|
||||
import androidx.compose.ui.graphics.drawscope.clipPath
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.R
|
||||
import io.element.android.libraries.designsystem.modifiers.blurCompat
|
||||
import io.element.android.libraries.designsystem.modifiers.blurredShapeShadow
|
||||
import io.element.android.libraries.designsystem.modifiers.canUseBlurMaskFilter
|
||||
import io.element.android.libraries.designsystem.preview.DayNightPreviews
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
|
@ -53,6 +44,7 @@ import io.element.android.libraries.theme.ElementTheme
|
|||
fun ElementLogoAtom(
|
||||
size: ElementLogoAtomSize,
|
||||
modifier: Modifier = Modifier,
|
||||
useBlurredShadow: Boolean = canUseBlurMaskFilter(),
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
) {
|
||||
val blur = if (darkTheme) 160.dp else 24.dp
|
||||
|
|
@ -66,22 +58,35 @@ fun ElementLogoAtom(
|
|||
.border(size.borderWidth, borderColor, RoundedCornerShape(size.cornerRadius)),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(size.outerSize)
|
||||
.shapeShadow(
|
||||
color = shadowColor,
|
||||
cornerRadius = size.cornerRadius,
|
||||
blurRadius = size.shadowRadius,
|
||||
offsetY = 8.dp,
|
||||
)
|
||||
)
|
||||
if (useBlurredShadow) {
|
||||
Box(
|
||||
Modifier
|
||||
.size(size.outerSize)
|
||||
.blurredShapeShadow(
|
||||
color = shadowColor,
|
||||
cornerRadius = size.cornerRadius,
|
||||
blurRadius = size.shadowRadius,
|
||||
offsetY = 8.dp,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
Modifier
|
||||
.size(size.outerSize)
|
||||
.shadow(
|
||||
elevation = size.shadowRadius,
|
||||
shape = RoundedCornerShape(size.cornerRadius),
|
||||
clip = false,
|
||||
ambientColor = shadowColor
|
||||
)
|
||||
)
|
||||
}
|
||||
Box(
|
||||
Modifier
|
||||
.clip(RoundedCornerShape(size.cornerRadius))
|
||||
.size(size.outerSize)
|
||||
.background(backgroundColor)
|
||||
.blur(blur)
|
||||
.blurCompat(blur)
|
||||
)
|
||||
Image(
|
||||
modifier = Modifier.size(size.logoSize),
|
||||
|
|
@ -121,44 +126,6 @@ sealed class ElementLogoAtomSize(
|
|||
)
|
||||
}
|
||||
|
||||
fun Modifier.shapeShadow(
|
||||
color: Color = Color.Black,
|
||||
cornerRadius: Dp = 0.dp,
|
||||
offsetX: Dp = 0.dp,
|
||||
offsetY: Dp = 0.dp,
|
||||
blurRadius: Dp = 0.dp,
|
||||
) = then(
|
||||
drawBehind {
|
||||
drawIntoCanvas { canvas ->
|
||||
val path = Path().apply {
|
||||
addRoundRect(RoundRect(Rect(Offset.Zero, size), CornerRadius(cornerRadius.toPx())))
|
||||
}
|
||||
|
||||
clipPath(path, ClipOp.Difference) {
|
||||
val paint = Paint()
|
||||
val frameworkPaint = paint.asFrameworkPaint()
|
||||
if (blurRadius != 0.dp) {
|
||||
frameworkPaint.maskFilter = BlurMaskFilter(blurRadius.toPx(), BlurMaskFilter.Blur.NORMAL)
|
||||
}
|
||||
frameworkPaint.color = color.toArgb()
|
||||
|
||||
val leftPixel = offsetX.toPx()
|
||||
val topPixel = offsetY.toPx()
|
||||
val rightPixel = size.width + topPixel
|
||||
val bottomPixel = size.height + leftPixel
|
||||
|
||||
canvas.drawRect(
|
||||
left = leftPixel,
|
||||
top = topPixel,
|
||||
right = rightPixel,
|
||||
bottom = bottomPixel,
|
||||
paint = paint,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@Composable
|
||||
@DayNightPreviews
|
||||
internal fun ElementLogoAtomMediumPreview() {
|
||||
|
|
@ -172,7 +139,19 @@ internal fun ElementLogoAtomLargePreview() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview(elementLogoAtomSize: ElementLogoAtomSize) {
|
||||
@DayNightPreviews
|
||||
internal fun ElementLogoAtomMediumNoBlurShadowPreview() {
|
||||
ContentToPreview(ElementLogoAtomSize.Medium, useBlurredShadow = false)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@DayNightPreviews
|
||||
internal fun ElementLogoAtomLargeNoBlurShadowPreview() {
|
||||
ContentToPreview(ElementLogoAtomSize.Large, useBlurredShadow = false)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ContentToPreview(elementLogoAtomSize: ElementLogoAtomSize, useBlurredShadow: Boolean = true) {
|
||||
ElementPreview {
|
||||
Box(
|
||||
Modifier
|
||||
|
|
@ -180,7 +159,7 @@ private fun ContentToPreview(elementLogoAtomSize: ElementLogoAtomSize) {
|
|||
.background(ElementTheme.colors.bgSubtlePrimary),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
ElementLogoAtom(elementLogoAtomSize)
|
||||
ElementLogoAtom(elementLogoAtomSize, useBlurredShadow = useBlurredShadow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package io.element.android.libraries.designsystem.components.preferences
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
|
@ -35,6 +37,7 @@ import io.element.android.libraries.designsystem.preview.PreviewGroup
|
|||
import io.element.android.libraries.designsystem.theme.components.Checkbox
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.toEnabledColor
|
||||
import io.element.android.libraries.designsystem.toSecondaryEnabledColor
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
|
|
@ -42,6 +45,7 @@ fun PreferenceCheckbox(
|
|||
title: String,
|
||||
isChecked: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
supportingText: String? = null,
|
||||
enabled: Boolean = true,
|
||||
icon: ImageVector? = null,
|
||||
showIconAreaIfNoIcon: Boolean = false,
|
||||
|
|
@ -60,13 +64,23 @@ fun PreferenceCheckbox(
|
|||
enabled = enabled,
|
||||
isVisible = showIconAreaIfNoIcon
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.weight(1f),
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
text = title,
|
||||
color = enabled.toEnabledColor(),
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.weight(1f),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
style = ElementTheme.typography.fontBodyLgRegular,
|
||||
text = title,
|
||||
color = enabled.toEnabledColor(),
|
||||
)
|
||||
if (supportingText != null) {
|
||||
Text(
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
text = supportingText,
|
||||
color = enabled.toSecondaryEnabledColor(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Checkbox(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterVertically),
|
||||
|
|
@ -83,10 +97,19 @@ internal fun PreferenceCheckboxPreview() = ElementThemedPreview { ContentToPrevi
|
|||
|
||||
@Composable
|
||||
private fun ContentToPreview() {
|
||||
PreferenceCheckbox(
|
||||
title = "Checkbox",
|
||||
icon = Icons.Default.Announcement,
|
||||
enabled = true,
|
||||
isChecked = true
|
||||
)
|
||||
Column {
|
||||
PreferenceCheckbox(
|
||||
title = "Checkbox",
|
||||
icon = Icons.Default.Announcement,
|
||||
enabled = true,
|
||||
isChecked = true
|
||||
)
|
||||
PreferenceCheckbox(
|
||||
title = "Checkbox with supporting text",
|
||||
supportingText = "Supporting text",
|
||||
icon = Icons.Default.Announcement,
|
||||
enabled = true,
|
||||
isChecked = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.modifiers
|
||||
|
||||
import android.graphics.BlurMaskFilter
|
||||
import android.os.Build
|
||||
import androidx.annotation.ChecksSdkIntAtLeast
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.BlurredEdgeTreatment
|
||||
import androidx.compose.ui.draw.blur
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.geometry.CornerRadius
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Rect
|
||||
import androidx.compose.ui.geometry.RoundRect
|
||||
import androidx.compose.ui.graphics.ClipOp
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Paint
|
||||
import androidx.compose.ui.graphics.Path
|
||||
import androidx.compose.ui.graphics.drawscope.clipPath
|
||||
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* @return true if the blur modifier is supported on the current OS version.
|
||||
*
|
||||
* The docs say the `blur` modifier is only supported on Android 12+:
|
||||
* https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).blur(androidx.compose.ui.unit.Dp,androidx.compose.ui.draw.BlurredEdgeTreatment)
|
||||
* */
|
||||
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
|
||||
fun canUseBlur(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||
|
||||
@Composable
|
||||
fun canUseBlurMaskFilter() = !LocalView.current.isHardwareAccelerated
|
||||
|
||||
fun Modifier.blurredShapeShadow(
|
||||
color: Color = Color.Black,
|
||||
cornerRadius: Dp = 0.dp,
|
||||
offsetX: Dp = 0.dp,
|
||||
offsetY: Dp = 0.dp,
|
||||
blurRadius: Dp = 0.dp,
|
||||
) = then(
|
||||
drawBehind {
|
||||
drawIntoCanvas { canvas ->
|
||||
val path = Path().apply {
|
||||
addRoundRect(RoundRect(Rect(Offset.Zero, size), CornerRadius(cornerRadius.toPx())))
|
||||
}
|
||||
|
||||
// Draw the blurred shadow, then cut out the shape from it
|
||||
clipPath(path, ClipOp.Difference) {
|
||||
val paint = Paint()
|
||||
val frameworkPaint = paint.asFrameworkPaint()
|
||||
if (blurRadius != 0.dp) {
|
||||
frameworkPaint.maskFilter = BlurMaskFilter(blurRadius.toPx(), BlurMaskFilter.Blur.NORMAL)
|
||||
}
|
||||
frameworkPaint.color = color.toArgb()
|
||||
|
||||
val leftPixel = offsetX.toPx()
|
||||
val topPixel = offsetY.toPx()
|
||||
val rightPixel = size.width + topPixel
|
||||
val bottomPixel = size.height + leftPixel
|
||||
|
||||
canvas.drawRect(
|
||||
left = leftPixel,
|
||||
top = topPixel,
|
||||
right = rightPixel,
|
||||
bottom = bottomPixel,
|
||||
paint = paint,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fun Modifier.blurCompat(
|
||||
radius: Dp,
|
||||
edgeTreatment: BlurredEdgeTreatment = BlurredEdgeTreatment.Rectangle
|
||||
): Modifier = composed {
|
||||
when {
|
||||
radius.value == 0f -> this
|
||||
canUseBlur() -> blur(radius, edgeTreatment)
|
||||
else -> this // Added in case we find a way to make this work on older devices
|
||||
}
|
||||
}
|
||||
|
|
@ -25,5 +25,11 @@ enum class FeatureFlags(
|
|||
LocationSharing(
|
||||
key = "feature.locationsharing",
|
||||
title = "Allow user to share location",
|
||||
),
|
||||
Polls(
|
||||
key = "feature.polls",
|
||||
title = "Polls",
|
||||
description = "Render poll events in the timeline",
|
||||
defaultValue = false,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class BuildtimeFeatureFlagProvider @Inject constructor() :
|
|||
return if (feature is FeatureFlags) {
|
||||
when (feature) {
|
||||
FeatureFlags.LocationSharing -> true
|
||||
FeatureFlags.Polls -> false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ fun FeaturePreferenceView(
|
|||
) {
|
||||
PreferenceCheckbox(
|
||||
title = feature.title,
|
||||
supportingText = feature.description,
|
||||
isChecked = feature.isEnabled,
|
||||
modifier = modifier,
|
||||
onCheckedChange = onCheckedChange
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ package io.element.android.libraries.featureflag.ui.model
|
|||
data class FeatureUiModel(
|
||||
val key: String,
|
||||
val title: String,
|
||||
val description: String?,
|
||||
val isEnabled: Boolean
|
||||
)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
|
||||
fun aFeatureUiModelList(): ImmutableList<FeatureUiModel> {
|
||||
return persistentListOf(
|
||||
FeatureUiModel("key1", "Display State Events", true),
|
||||
FeatureUiModel("key2", "Display Room Events", false)
|
||||
FeatureUiModel("key1", "Display State Events", "Show state events in the timeline", true),
|
||||
FeatureUiModel("key2", "Display Room Events", null, false),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6d2eab27a1132893542b240399a4003b4049b72903a822077f69dd9dafd26f71
|
||||
size 299106
|
||||
oid sha256:2cc8d498816a04c537ad2835068a2badab656aa723a900b471c8f79320d7967c
|
||||
size 300473
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fbad2f74e329a424e75ef96cb0c427a7baba044f3267346756324c39ebd6add6
|
||||
size 404196
|
||||
oid sha256:634dc94c58f6e7aed8abf9c11f33e81a65e81c439b247321a398e3728d5696d4
|
||||
size 401397
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:56f53e2c13480d5f31d38c671612c81fa802e1f35a55ada99d544917f01b91ba
|
||||
size 338952
|
||||
oid sha256:4bf8563c80e874ff79850e37bbf71609aac72c62c74cbe8255e403bd00feadc3
|
||||
size 326514
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cfe3663daab250bcd733ab746e4864472691b40cf927a3cd73d15b323dec2b68
|
||||
size 329945
|
||||
oid sha256:45984b598d30a2511e03644927a9f1f34b4173f2eebb8a328a19df8643385f18
|
||||
size 317243
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c449e6e4162f12a6be7faa668b930b294489ae217c2a7493f5671145a926079e
|
||||
size 340944
|
||||
oid sha256:1d96057db48fd7e3461fde86b84c09688c0af49e51bcd94affa2df9c9785b6f5
|
||||
size 327755
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0355120442254880360b982df6c2c7cce84a471f632436c96e79ffafed35de14
|
||||
size 324378
|
||||
oid sha256:4007453c80be5700ec9942983ef903a2404e7e3879d82c189a5e95687916e8eb
|
||||
size 310597
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5d05151967955c961ca47619de2f28f86d0350299b61fbef0371c1706439a844
|
||||
size 421908
|
||||
oid sha256:5b07c105d41caf87c34a506138ff5d43df853d9b7b7143e0099f222886ca217e
|
||||
size 420316
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3a2056882e65afe8fc2d0dc60efc7912ca5674acb57e3690136a8704f9f063ed
|
||||
size 407942
|
||||
oid sha256:738ee59035ecbc006ccd43ff10ce847d6d741da780b3e189c221b55a1b6ec06c
|
||||
size 405327
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6521d409bc1fc70fa422ffec400d9f20d0b7fe16adebb7f5b0a9e5f135328ffc
|
||||
size 422213
|
||||
oid sha256:1b3ba2db52bd7ee1713ba1b276b0e3a4a7edf406a8833027d548c9fdf4dbe838
|
||||
size 419123
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d39cfdb0db12a6d14f3105aa168ea002a845d2083f07ecfabe0858739507018d
|
||||
size 396789
|
||||
oid sha256:4bd69417650f09e240405d839464ba716d55d01e6230a9aa8b923460b4c88443
|
||||
size 393093
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4a9a3902dd33ab3e528fa9c534302228113cc468914025766a21397ad3eda9e2
|
||||
size 45064
|
||||
oid sha256:aa65609944cd9118668fcdf75a7882111230cceebbdc68bab764f51929dfc6f2
|
||||
size 49584
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4a9a3902dd33ab3e528fa9c534302228113cc468914025766a21397ad3eda9e2
|
||||
size 45064
|
||||
oid sha256:aa65609944cd9118668fcdf75a7882111230cceebbdc68bab764f51929dfc6f2
|
||||
size 49584
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cd1cc710443af62efddf0ea165a6289912f471f669803255368d3266b872f5f6
|
||||
size 49829
|
||||
oid sha256:c571049a9cbf3dc13d8a700aa4d3639f8fca89db749c5ebfbb59ca6a0bb0b9eb
|
||||
size 54206
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cd1cc710443af62efddf0ea165a6289912f471f669803255368d3266b872f5f6
|
||||
size 49829
|
||||
oid sha256:c571049a9cbf3dc13d8a700aa4d3639f8fca89db749c5ebfbb59ca6a0bb0b9eb
|
||||
size 54206
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3f76220968b3e28b2c1ddd91b4036bf037a98e97c859e8616314ed953862cc64
|
||||
size 42525
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3321dd27c1fbe47df862dad9b591faf9279da1ea4eb66b7b900d8c962280a74e
|
||||
size 31811
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ca4e1e3cd5d7cb9fd8416bc7074272b759bbc501993829b6edef6809cf519aee
|
||||
size 27532
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8615ceb43c29becd4cfe6062d8fc844b15b717e8f2e5d7b151bdc4478de59381
|
||||
size 20607
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:06813451633c48fccac6f70810ecb9465946b643376fccd61312b6064b0a3a40
|
||||
size 11518
|
||||
oid sha256:7ba8a794a8b65f412806ee1accc4f8678b046e880fd76c038eb054155ba514ea
|
||||
size 28463
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue