Merge pull request #8 from archem-team/feat/discover

Change Discover flow from webview to application implementation
This commit is contained in:
Abron Studio 2025-08-07 09:56:48 +03:30 committed by GitHub
commit 062375287d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 1660 additions and 406 deletions

View File

@ -166,7 +166,7 @@ class MainActivityViewModel @Inject constructor(
try {
val res = RevoltHttp.get("/".api())
return res.status.value == 200
} catch (e: Exception) {
} catch (_: Exception) {
return false
}
}
@ -225,7 +225,7 @@ class MainActivityViewModel @Inject constructor(
val canReachRevolt = canReachRevolt()
val valid = try {
RevoltAPI.checkSessionToken(token)
} catch (e: Throwable) {
} catch (_: Throwable) {
false
}
@ -275,7 +275,7 @@ class MainActivityViewModel @Inject constructor(
viewModelScope.launch {
kvStorage.remove("sessionToken")
kvStorage.remove("sessionId")
startWithDestination("login/greeting")
startWithDestination("choose-platform")
}
}
@ -430,7 +430,6 @@ class MainActivity : AppCompatActivity() {
val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo)
val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo)
val RevoltTweenDp: FiniteAnimationSpec<Dp> = tween(400, easing = EaseInOutExpo)
val RevoltTweenColour: FiniteAnimationSpec<Color> = tween(400, easing = EaseInOutExpo)
val NavTweenInt: FiniteAnimationSpec<IntOffset> = tween(350, easing = EaseInOutExpo)
val NavTweenFloat: FiniteAnimationSpec<Float> = tween(350, easing = EaseInOutExpo)
@ -694,10 +693,11 @@ fun AppEntrypoint(
val channelId = backStackEntry.arguments?.getString("channelId") ?: ""
ChannelScreen(
channelId = channelId,
onToggleDrawer = {},
useDrawer = false,
useBackButton = true,
backToChannelsScreen = {},
backToChannelsScreen = {
navController.navigate("main")
},
backButtonAction = {
navController.popBackStack()
},

View File

@ -91,14 +91,14 @@ private val PLATFORM_URLS = mapOf(
kjbook = "https://revoltchat.github.io/android"
),
ApplicationPlatform.PEP to PlatformUrls(
base = "https://a-pep.peptide.chat/api",
base = "https://pepchat.io/api",
marketing = "https://peptide.chat",
files = "https://cdn.pepusercontent.com",
january = "https://a-pep.peptide.chat/january",
january = "https://pepchat.io/january",
app = "https://peptide.chat",
invites = "https://pep.gg",
websocket = "wss://a-pep.peptide.chat/ws",
autumn = "https://a-pep.peptide.chat/autumn",
websocket = "wss://pepchat.io/ws",
autumn = "https://pepchat.io/autumn",
// TODO: Replace with correct URL
kjbook = "https://revoltchat.github.io/android"
// TODO: Replace with correct URL
@ -220,7 +220,7 @@ object RevoltAPI {
* The currently selected platform.
* Default is REVOLT.
*/
var selectedApplicationPlatform: ApplicationPlatform = ApplicationPlatform.REVOLT
var selectedApplicationPlatform: ApplicationPlatform = ApplicationPlatform.PEP
private set
/**
@ -258,7 +258,7 @@ object RevoltAPI {
// URL getter functions
fun getCurrentBaseUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.base }
fun getCurrentMarketingUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.marketing }
fun getCurrentFilesUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.files }
fun getCurrentFilesUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.autumn }
fun getCurrentJanuaryUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.january }
fun getCurrentAppUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.app }
fun getCurrentInvitesUrl(): String = getUrlForPlatform(selectedApplicationPlatform) { it.invites }

View File

@ -0,0 +1,162 @@
package chat.revolt.api.routes.googlesheets
import chat.revolt.api.RevoltHttp
import chat.revolt.api.RevoltJson
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
/**
* Service for fetching and parsing Google Sheets data
* This supports both JSON and CSV formats from published Google Sheets
*/
object GoogleSheetsService {
/**
* Fetches data from a Google Sheet and maps it to a list of objects of type T
* @param sheetUrl The URL of the published Google Sheet (CSV or JSON)
* @param mapper A function that maps a row (as a Map<String, String>) to an object of type T
* @return A list of objects of type T
*/
suspend inline fun <reified T> fetchSheetData(
sheetUrl: String,
crossinline mapper: (Map<String, String>) -> T
): List<T> = withContext(Dispatchers.IO) {
try {
val response = RevoltHttp.get(sheetUrl).bodyAsText()
// Determine if the response is CSV or JSON
if (sheetUrl.contains("output=csv") || response.startsWith("\"") || response.contains(",")) {
parseCSV(response, mapper)
} else {
parseJSON(response, mapper)
}
} catch (e: Exception) {
e.printStackTrace()
emptyList()
}
}
/**
* Parse CSV data from Google Sheets
*/
inline fun <reified T> parseCSV(
csvData: String,
crossinline mapper: (Map<String, String>) -> T
): List<T> {
// Split the CSV into lines
val lines = csvData.lines().filter { it.isNotBlank() }
if (lines.isEmpty()) return emptyList()
// Parse header row
val headers = lines[0].split(",").map {
it.trim().removeSurrounding("\"")
}
// Parse data rows
return lines.drop(1).map { line ->
val values = parseCSVLine(line)
val rowData = mutableMapOf<String, String>()
headers.forEachIndexed { index, header ->
if (index < values.size) {
rowData[header] = values[index]
}
}
mapper(rowData)
}
}
/**
* Parse a single CSV line, handling quoted values properly
*/
fun parseCSVLine(line: String): List<String> {
val values = mutableListOf<String>()
var currentValue = StringBuilder()
var inQuotes = false
for (char in line) {
when {
char == '\"' -> inQuotes = !inQuotes
char == ',' && !inQuotes -> {
values.add(currentValue.toString().trim().removeSurrounding("\""))
currentValue = StringBuilder()
}
else -> currentValue.append(char)
}
}
// Add the last value
values.add(currentValue.toString().trim().removeSurrounding("\""))
return values
}
/**
* Parse JSON data from Google Sheets
*/
inline fun <reified T> parseJSON(
jsonData: String,
crossinline mapper: (Map<String, String>) -> T
): List<T> {
val sheetResponse = RevoltJson.decodeFromString<GoogleSheetResponse>(jsonData)
// Convert the sheet data to a list of objects
val headers = sheetResponse.feed.entry
.take(sheetResponse.feed.entry.firstOrNull()?.content?.columnCount ?: 0)
.mapIndexed { index, entry ->
"gsx\$column${index + 1}" to entry.title.text
}.toMap()
val rows = sheetResponse.feed.entry.chunked(headers.size)
.drop(1) // Skip header row
.map { rowEntries ->
val rowData = mutableMapOf<String, String>()
rowEntries.forEachIndexed { index, entry ->
val columnName = headers["gsx\$column${index + 1}"] ?: "column${index + 1}"
rowData[columnName] = entry.content.text
}
mapper(rowData)
}
return rows
}
}
/**
* Data classes for parsing Google Sheets API response
*/
@Serializable
data class GoogleSheetResponse(
val feed: Feed
)
@Serializable
data class Feed(
val entry: List<Entry>
)
@Serializable
data class Entry(
val title: Title,
val content: Content
)
@Serializable
data class Title(
@SerialName("\$t")
val text: String
)
@Serializable
data class Content(
@SerialName("\$t")
val text: String,
@SerialName("columnCount")
val columnCount: Int = 0
)

View File

@ -0,0 +1,51 @@
package chat.revolt.api.routes.googlesheets
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.serialization.Serializable
/**
* Repository for fetching server data from a Google Sheet
*/
class ServerDataRepository {
/**
* Fetches server data from Google Sheets and returns as a Flow
* @param sheetUrl The URL of the published Google Sheet (CSV or JSON)
* @return Flow of ServerData list
*/
fun getServers(sheetUrl: String): Flow<List<ServerData>> = flow {
val servers = GoogleSheetsService.fetchSheetData(
sheetUrl = sheetUrl
) { rowData ->
ServerData(
id = rowData["id"] ?: "",
name = rowData["name"] ?: "",
description = rowData["description"] ?: "",
inviteCode = rowData["inviteCode"] ?: "",
disabled = when (rowData["disabled"]?.lowercase()) {
"false" -> false
else -> true
},
showColor = rowData["showcolor"]
)
}
emit(servers)
}.flowOn(Dispatchers.IO)
}
/**
* Data class representing a server
*/
@Serializable
data class ServerData(
val id: String,
val name: String,
val description: String,
val inviteCode: String,
val disabled: Boolean,
val showColor: String?,
)

View File

@ -63,7 +63,6 @@ const val SWIPE_TO_REPLY_THRESHOLD = -450f
fun RegularMessage(
message: Message,
channel: Channel?,
drawerIsOpen: Boolean,
setDrawerGestureEnabled: (Boolean) -> Unit,
setDisableScroll: (Boolean) -> Unit,
showMessageBottomSheet: (String) -> Unit,
@ -77,7 +76,6 @@ fun RegularMessage(
var offsetX by remember { mutableFloatStateOf(0f) }
val animOffsetX by animateFloatAsState(
when {
drawerIsOpen -> 0f
offsetX > -20f -> 0f
else -> offsetX
},
@ -103,7 +101,7 @@ fun RegularMessage(
label = "Swipe to Reply indicator foreground"
)
var onFingerMoveHandler: (List<PointerInputChange>) -> Unit =
val onFingerMoveHandler: (List<PointerInputChange>) -> Unit =
{ changeList: List<PointerInputChange> ->
changeList.firstOrNull()
?.let {

View File

@ -0,0 +1,337 @@
package chat.revolt.composables.screens.chat.discover
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.graphics.toColorInt
import androidx.hilt.navigation.compose.hiltViewModel
import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.routes.googlesheets.ServerData
@Composable
fun DiscoverServersList(
onJoinToServerSuccess: (String) -> Unit,
) {
val viewModel = hiltViewModel<DiscoverServersListViewModel>()
val uiState by viewModel.uiState.collectAsState()
// Handle server invite dialog
uiState.selectedInviteCode?.let { inviteCode ->
// Find the server with this invite code
val selectedServer = uiState.servers.find { it.inviteCode == inviteCode }
selectedServer?.let { server ->
ServerInviteHandler(
inviteCode = inviteCode,
viewModel = viewModel,
onDismiss = {
viewModel.setSelectedInviteCode(null)
},
onJoinSuccess = { serverId ->
onJoinToServerSuccess(serverId)
}
)
}
}
Column(
modifier = Modifier
.padding(top = 24.dp, start = 16.dp, end = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
modifier = Modifier
.padding(8.dp),
painter = painterResource(R.drawable.discover_character_image),
contentDescription = null,
)
Text(
text = stringResource(R.string.discover_servers),
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = stringResource(R.string.discover_servers_description),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(16.dp))
when {
uiState.isLoading -> {
CircularProgressIndicator(
modifier = Modifier
.padding(16.dp)
.align(Alignment.CenterHorizontally)
)
}
uiState.error != null -> {
Text(stringResource(R.string.error))
}
uiState.servers.isEmpty() -> {
Text(stringResource(R.string.no_servers_found))
}
else -> {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.weight(1f)
) {
items(uiState.servers) { server ->
// Check if the server is already joined
val isJoined = isServerAlreadyJoined(server.id)
ServerItem(
server = server,
isProcessing = uiState.processingServerId == server.id,
isJoined = isServerAlreadyJoined(server.id),
onClick = {
if (isJoined) {
// If already joined, navigate directly to server channels
onJoinToServerSuccess(server.id)
} else if (server.inviteCode.isNotEmpty()) {
// If not joined, load server data and show invite dialog
viewModel.loadServerDataAndShowDialog(
server.inviteCode,
server.id
)
}
}
)
}
}
}
}
}
}
private fun isServerAlreadyJoined(serverId: String): Boolean {
// Check if the server exists in RevoltAPI.serverCache
return RevoltAPI.serverCache.containsKey(serverId)
}
@Composable
fun ServerItem(
server: ServerData,
isJoined: Boolean,
onClick: () -> Unit,
isProcessing: Boolean = false
) {
// Safely convert the hex string to a Color, or return null if invalid
fun parseColorOrNull(hex: String?): Color? {
return hex?.let { raw ->
val normalized = if (raw.startsWith("#")) raw else "#$raw"
try {
Color(normalized.toColorInt())
} catch (_: IllegalArgumentException) {
null
}
}
}
// Determine card colors based on server.showColor
val containerColor = parseColorOrNull(server.showColor)
val cardColors = if (containerColor != null) {
CardDefaults.cardColors(containerColor = containerColor)
} else {
CardDefaults.cardColors()
}
// Calculate alpha values based on disabled state
val contentAlpha = if (server.disabled) 0.5f else 1.0f
val descriptionAlpha = if (server.disabled) 0.4f else 0.7f
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clickable(enabled = !isProcessing) { onClick() },
colors = cardColors,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(R.drawable.three_person),
contentDescription = "",
colorFilter = ColorFilter.tint(
color = MaterialTheme.colorScheme.onBackground.copy(alpha = contentAlpha)
)
)
Spacer(modifier = Modifier.width(12.dp))
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = server.name,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onBackground.copy(
alpha = contentAlpha
)
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = server.description,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(
alpha = descriptionAlpha,
),
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
Spacer(modifier = Modifier.height(12.dp))
if (isProcessing) {
CircularProgressIndicator(
modifier = Modifier
.size(24.dp),
strokeWidth = 2.dp
)
} else {
IconButton(
onClick = onClick,
) {
Box(
modifier = Modifier
.fillMaxSize()
) {
if (isJoined) {
// Show tick icon with green background for joined servers
Box(
modifier = Modifier
.size(20.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.primary) // Green color
.align(Alignment.Center),
contentAlignment = Alignment.Center
) {
Image(
modifier = Modifier.size(16.dp),
painter = painterResource(R.drawable.icn_check_24dp),
contentDescription = "Already joined",
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimary)
)
}
} else {
// Show arrow icon for servers not joined yet
Image(
painter = painterResource(R.drawable.icn_arrow_forward_24dp),
contentDescription = "Join server",
modifier = Modifier
.align(Alignment.Center),
colorFilter = ColorFilter.tint(
color = MaterialTheme.colorScheme.onBackground.copy(alpha = contentAlpha)
)
)
}
}
}
}
}
}
}
@Preview
@Composable
private fun ServerItemPreview() {
val server = ServerData(
id = "1",
name = "Revolt Lounge",
description = "The official Revolt server. Hang out, chat, and get help with Revolt.",
inviteCode = "revolt",
disabled = false,
showColor = null
)
ServerItem(
server = server,
onClick = {},
isJoined = false,
isProcessing = false
)
}
@Preview
@Composable
private fun ColorfulServerItemPreview() {
val server = ServerData(
id = "1",
name = "Revolt Lounge",
description = "The official Revolt server. Hang out, chat, and get help with Revolt.",
inviteCode = "revolt",
disabled = false,
showColor = "#1591ea"
)
ServerItem(
server = server,
onClick = {},
isJoined = false,
isProcessing = false
)
}
@Preview
@Composable
private fun JoinedServerItemPreview() {
val server = ServerData(
id = "1",
name = "Revolt Lounge",
description = "The official Revolt server. Hang out, chat, and get help with Revolt.",
inviteCode = "revolt",
disabled = false,
showColor = null,
)
ServerItem(
server = server,
onClick = {},
isJoined = true,
isProcessing = false
)
}

View File

@ -0,0 +1,157 @@
package chat.revolt.composables.screens.chat.discover
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import chat.revolt.api.RevoltError
import chat.revolt.api.routes.googlesheets.ServerData
import chat.revolt.api.routes.googlesheets.ServerDataRepository
import chat.revolt.api.routes.invites.fetchInviteByCode
import chat.revolt.api.routes.invites.joinInviteByCode
import chat.revolt.api.schemas.Invite
import chat.revolt.api.schemas.InviteJoined
import chat.revolt.api.schemas.RsResult
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* Combined UI state for the discover servers screen
*/
data class DiscoverUiState(
// Server list state
val servers: List<ServerData> = emptyList(),
val isLoading: Boolean = false,
val error: String? = null,
// Server invite state
val selectedInviteCode: String? = null,
val processingServerId: String? = null,
val loadedInviteData: Invite? = null,
val loadedError: RevoltError? = null
)
@HiltViewModel
class DiscoverServersListViewModel @Inject constructor(
private val serverDataRepository: ServerDataRepository,
) : ViewModel() {
// Single UI state
private val _uiState = MutableStateFlow(DiscoverUiState())
val uiState: StateFlow<DiscoverUiState> = _uiState.asStateFlow()
// Initialize
init {
loadServers()
}
/**
* Load server list from repository
*/
fun loadServers() {
updateState { it.copy(isLoading = true, error = null) }
viewModelScope.launch {
try {
val csvUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRY41D-NgTE6bC3kTN3dRpisI-DoeHG8Eg7n31xb1CdydWjOLaphqYckkTiaG9oIQSWP92h3NE-7cpF/pub?gid=0&single=true&output=csv"
serverDataRepository.getServers(csvUrl).collect { servers ->
updateState { it.copy(servers = servers, isLoading = false) }
}
} catch (e: Exception) {
updateState {
it.copy(
error = e.message ?: "Unknown error occurred",
isLoading = false
)
}
}
}
}
/**
* Load server data and show dialog when ready
*/
fun loadServerDataAndShowDialog(inviteCode: String, serverId: String) {
updateState {
it.copy(
loadedInviteData = null,
processingServerId = serverId
)
}
viewModelScope.launch {
try {
val result = fetchInviteByCode(inviteCode)
if (result.ok) {
updateState {
it.copy(
loadedInviteData = result.value,
selectedInviteCode = inviteCode,
processingServerId = null
)
}
} else {
updateState {
it.copy(
loadedError = result.error,
selectedInviteCode = inviteCode,
processingServerId = null
)
}
}
} catch (_: Exception) {
updateState {
it.copy(
loadedError = RevoltError("Unknown"),
selectedInviteCode = inviteCode,
processingServerId = null
)
}
}
}
}
/**
* Join server without showing loading in the server list
*/
fun joinServerWithoutProcessingIndicator(inviteCode: String): Flow<RsResult<InviteJoined, RevoltError>> = flow {
try {
emit(joinInviteByCode(inviteCode))
} catch (_: Exception) {
emit(RsResult.err(RevoltError("Unknown")))
}
}.flowOn(Dispatchers.IO)
/**
* Clear loaded data when dialog is dismissed
*/
fun clearLoadedData() {
updateState {
it.copy(
loadedInviteData = null,
loadedError = null,
selectedInviteCode = null
)
}
}
/**
* Set selected invite code
*/
fun setSelectedInviteCode(code: String?) {
updateState { it.copy(selectedInviteCode = code) }
}
/**
* Helper function to update state
*/
private fun updateState(update: (DiscoverUiState) -> DiscoverUiState) {
_uiState.value = update(_uiState.value)
}
}

View File

@ -0,0 +1,273 @@
package chat.revolt.composables.screens.chat.discover
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.RevoltError
import chat.revolt.api.schemas.Invite
import chat.revolt.composables.generic.IconPlaceholder
import chat.revolt.composables.generic.RemoteImage
@Composable
fun ServerInviteDialog(
isLoading: Boolean,
invite: Invite?,
error: RevoltError?,
onJoinClick: () -> Unit,
onDismiss: () -> Unit
) {
if (error != null) {
AlertDialog(
onDismissRequest = onDismiss,
icon = {
Image(
painter = painterResource(R.drawable.link_no_valid_img),
contentDescription = null,
)
},
title = {
Text(
text = stringResource(id = R.string.invite_error_header),
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
},
text = {
Column {
Text(
text = when (error.type) {
"NotFound" -> stringResource(id = R.string.invite_error_invalid_invite)
"Banned" -> stringResource(id = R.string.invite_error_banned)
else -> stringResource(id = R.string.invite_error_unknown)
},
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.height(32.dp))
Button(
onClick = onDismiss,
modifier = Modifier.fillMaxWidth(),
) {
Text(text = stringResource(id = R.string.spark_early_access_cta))
}
}
},
confirmButton = {}
)
return
}
if (invite == null) {
// This shouldn't happen, but handle it just in case
return
}
AlertDialog(
onDismissRequest = onDismiss,
confirmButton = {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Bottom // Align buttons to the bottom
) {
Button(
onClick = onJoinClick,
modifier = Modifier.fillMaxWidth(),
enabled = !isLoading
) {
if (isLoading) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(18.dp),
strokeWidth = 2.dp
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = stringResource(id = R.string.joining))
}
} else {
Text(text = stringResource(id = R.string.invite_join))
}
}
TextButton(
onClick = onDismiss,
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(id = R.string.invite_cancel))
}
}
},
text = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
if (invite.serverIcon != null) {
RemoteImage(
url = "${RevoltAPI.getCurrentFilesUrl()}/icons/${invite.serverIcon.id}/${invite.serverIcon.filename}",
allowAnimation = false,
description = invite.serverName ?: stringResource(id = R.string.unknown),
modifier = Modifier
.size(64.dp)
.clip(CircleShape)
)
} else {
IconPlaceholder(
name = invite.serverName ?: stringResource(id = R.string.unknown),
modifier = Modifier
.size(64.dp)
.clip(CircleShape)
)
}
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.invite_message),
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = invite.serverName ?: stringResource(id = R.string.unknown),
textAlign = TextAlign.Center,
fontSize = 26.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.fillMaxWidth()
)
// Invited by section
if (invite.userName != null) {
Spacer(modifier = Modifier.height(16.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.border(
width = 1.dp,
color = MaterialTheme.colorScheme.outlineVariant,
shape = MaterialTheme.shapes.large
)
.padding(horizontal = 12.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = "Invited by")
Row(
verticalAlignment = Alignment.CenterVertically,
) {
if (invite.userAvatar != null) {
RemoteImage(
url = "${RevoltAPI.getCurrentFilesUrl()}/avatars/${invite.userAvatar.id}/${invite.userAvatar.filename}",
description = invite.userName,
modifier = Modifier
.size(24.dp)
.clip(CircleShape)
)
} else {
IconPlaceholder(
name = invite.userName, modifier = Modifier
.size(24.dp)
.clip(CircleShape), fontSize = 12.sp
)
}
Spacer(modifier = Modifier.width(4.dp))
Text(text = invite.userName, fontWeight = FontWeight.SemiBold)
}
}
}
if (invite.memberCount != null) {
Spacer(modifier = Modifier.height(8.dp))
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(R.drawable.three_person),
contentDescription = null,
colorFilter = ColorFilter.tint(
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(
alpha = 0.6f
)
)
)
Text(
text = stringResource(
id = R.string.members_count,
invite.memberCount
),
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(
alpha = 0.6f
)
)
}
}
}
},
)
}
@Preview
@Composable
fun ServerInviteDialogPreviewError() {
ServerInviteDialog(
isLoading = false,
invite = null,
error = RevoltError(type = "NotFound"),
onJoinClick = {},
onDismiss = {}
)
}
@Preview
@Composable
fun ServerInviteDialogPreviewSuccess() {
val invite = Invite(
serverName = "Revolt Test Server",
serverIcon = null, // Replace with a real AutumnResource if needed for preview
memberCount = 123,
userName = "TestUser",
userAvatar = null // Replace with a real AutumnResource if needed for preview
)
ServerInviteDialog(
isLoading = false,
invite = invite,
error = null,
onJoinClick = {},
onDismiss = {}
)
}

View File

@ -0,0 +1,61 @@
package chat.revolt.composables.screens.chat.discover
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.hilt.navigation.compose.hiltViewModel
import chat.revolt.api.RevoltError
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@Composable
fun ServerInviteHandler(
inviteCode: String,
viewModel: DiscoverServersListViewModel = hiltViewModel(),
onDismiss: () -> Unit = {},
onJoinSuccess: (String) -> Unit = {}
) {
val scope = rememberCoroutineScope()
var isJoining by remember { mutableStateOf(false) }
var showDialog by remember { mutableStateOf(true) }
var error by remember { mutableStateOf<RevoltError?>(null) }
// Get the UI state
val uiState by viewModel.uiState.collectAsState()
if (showDialog) {
ServerInviteDialog(
isLoading = isJoining,
invite = uiState.loadedInviteData,
error = error ?: uiState.loadedError,
onJoinClick = {
isJoining = true
scope.launch {
// Don't set the processing server ID here to avoid showing loading in the list
viewModel.joinServerWithoutProcessingIndicator(inviteCode).collectLatest { result ->
isJoining = false
if (result.ok) {
showDialog = false
viewModel.clearLoadedData()
uiState.loadedInviteData?.serverId?.let { serverId ->
onJoinSuccess(serverId)
}
} else {
error = result.error
}
}
}
},
onDismiss = {
showDialog = false
viewModel.clearLoadedData()
onDismiss()
}
)
}
}

View File

@ -1,9 +1,7 @@
package chat.revolt.composables.screens.chat.drawer
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
@ -30,13 +28,13 @@ import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@ -53,7 +51,6 @@ import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -69,10 +66,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import chat.revolt.R
import chat.revolt.api.RevoltAPI
import chat.revolt.api.internals.CategorisedChannelList
@ -94,8 +89,8 @@ import chat.revolt.composables.generic.RemoteImage
import chat.revolt.composables.generic.UserAvatar
import chat.revolt.composables.generic.presenceFromStatus
import chat.revolt.composables.screens.chat.ChannelIcon
import chat.revolt.composables.screens.chat.discover.DiscoverServersList
import chat.revolt.screens.chat.ChatRouterDestination
import chat.revolt.screens.chat.LocalIsConnected
import chat.revolt.sheets.ChannelContextSheet
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@ -109,10 +104,10 @@ fun ChannelSideDrawer(
onShowServerContextSheet: (String) -> Unit,
showSettingsIcon: Boolean,
onOpenSettings: () -> Unit,
topNav: NavController,
onShowAddServerSheet: () -> Unit,
modifier: Modifier = Modifier
) {
val server = RevoltAPI.serverCache[currentServer]
val categorisedChannels = server?.let {
ChannelUtils.categoriseServerFlat(it)
@ -122,7 +117,6 @@ fun ChannelSideDrawer(
LaunchedEffect(currentDestination) {
if ((currentDestination is ChatRouterDestination.ServersChannels) && currentServer != null) {
val channelIndex = categorisedChannels?.indexOfFirst {
when (it) {
is CategorisedChannelList.Channel -> it.channel.id == currentDestination.serverID
else -> false
@ -153,17 +147,6 @@ fun ChannelSideDrawer(
), label = "Server banner height"
)
val serverInfoOffset by animateDpAsState(
if (LocalIsConnected.current)
WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
else
0.dp,
animationSpec = spring(
stiffness = Spring.StiffnessMediumLow,
visibilityThreshold = Dp.VisibilityThreshold
)
)
// - Take the list of servers and filter them by the ones that are in the ordering.
// - Sort the servers that are in the ordering using the ordering.
// - Add the servers that aren't in the ordering to the end of the list.
@ -200,28 +183,14 @@ fun ChannelSideDrawer(
}
}
val scope = rememberCoroutineScope()
Row(modifier.fillMaxSize()) {
LazyColumn(
Modifier.width(64.dp),
verticalArrangement = Arrangement.spacedBy(6.dp),
horizontalAlignment = Alignment.CenterHorizontally,
contentPadding = PaddingValues(
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
)
) {
stickyHeader(key = "self") {
Column(Modifier.background(MaterialTheme.colorScheme.background)) {
AnimatedVisibility(LocalIsConnected.current) {
Spacer(
Modifier
.height(
WindowInsets.statusBars.asPaddingValues()
.calculateTopPadding()
)
)
}
UserAvatar(
username = RevoltAPI.userCache[RevoltAPI.selfId]?.let {
User.resolveDefaultName(
@ -238,7 +207,7 @@ fun ChannelSideDrawer(
size = 48.dp,
presenceSize = 16.dp,
onClick = {
onDestinationChanged(ChatRouterDestination.defaultForDMList)
onDestinationChanged(ChatRouterDestination.Home)
},
onLongClick = onLongPressAvatar,
modifier = Modifier
@ -315,6 +284,47 @@ fun ChannelSideDrawer(
)
}
item(key = "discover") {
Box(
Modifier
.padding(8.dp)
.clip(RoundedCornerShape(16.dp))
.clickable {
onDestinationChanged(
ChatRouterDestination.Discover
)
}
.size(48.dp)
.background(MaterialTheme.colorScheme.onPrimary),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(R.drawable.icn_explore_24dp),
contentDescription = stringResource(R.string.discover_alt)
)
}
}
item(key = "add_server") {
Box(
Modifier
.padding(8.dp)
.clip(CircleShape)
.clickable {
onShowAddServerSheet()
}
.size(48.dp)
.background(MaterialTheme.colorScheme.onPrimary),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(R.drawable.icn_add_24dp),
contentDescription = stringResource(R.string.server_plus_alt)
)
}
}
items(
serverList.size,
key = { serverList[it].id ?: it }
@ -389,42 +399,6 @@ fun ChannelSideDrawer(
}
}
item(key = "add_server") {
Box(
Modifier
.padding(8.dp)
.clip(CircleShape)
.clickable {
onShowAddServerSheet()
}
.size(48.dp),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(R.drawable.icn_add_24dp),
contentDescription = stringResource(R.string.server_plus_alt)
)
}
}
item(key = "discover") {
Box(
Modifier
.padding(8.dp)
.clip(CircleShape)
.clickable {
topNav.navigate("discover")
}
.size(48.dp),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(R.drawable.icn_explore_24dp),
contentDescription = stringResource(R.string.discover_alt)
)
}
}
if (showSettingsIcon) {
item(key = "settings") {
Box(
@ -447,23 +421,14 @@ fun ChannelSideDrawer(
}
Column(
Modifier
.background(MaterialTheme.colorScheme.surfaceContainer)
.weight(1f)
.clip(shape = RoundedCornerShape(topStart = 24.dp))
.background(color = MaterialTheme.colorScheme.surfaceContainer)
.weight(weight = 1f)
.fillMaxHeight()
) {
Box(
Modifier
.clip(
MaterialTheme.shapes.medium.copy(
topStart = CornerSize(0.dp),
topEnd = CornerSize(0.dp)
)
)
.height(
serverBannerHeight + WindowInsets.statusBars.asPaddingValues()
.calculateTopPadding()
)
//.offset(y = WindowInsets.statusBars.asPaddingValues().calculateTopPadding())
.height(serverBannerHeight)
) {
if (server?.banner != null) {
RemoteImage(
@ -495,8 +460,7 @@ fun ChannelSideDrawer(
Row(
Modifier
.padding(16.dp)
.offset(y = serverInfoOffset),
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
CompositionLocalProvider(
@ -538,7 +502,7 @@ fun ChannelSideDrawer(
Text(
text = when (currentServer) {
null -> stringResource(R.string.direct_messages)
null -> stringResource(if (currentDestination is ChatRouterDestination.Discover) R.string.discover_servers else R.string.direct_messages)
else -> server?.name ?: stringResource(R.string.unknown)
},
style = MaterialTheme.typography.titleMedium,
@ -563,30 +527,35 @@ fun ChannelSideDrawer(
}
}
}
if (currentServer == null) {
DirectMessagesChannelListRenderer(
currentDestination,
onDestinationChanged,
channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it }
if (currentDestination is ChatRouterDestination.Discover) {
DiscoverServersList(
onJoinToServerSuccess = navigateToServer
)
} else {
ServerChannelListRenderer(
categorisedChannels,
currentDestination,
onDestinationChanged,
channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it },
serverId = currentServer
)
if (currentServer == null) {
DirectMessagesChannelListRenderer(
currentDestination,
onDestinationChanged,
channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it }
)
} else {
ServerChannelListRenderer(
categorisedChannels,
currentDestination,
onDestinationChanged,
channelListState,
onOpenChannelContextSheet = { channelContextSheetTarget = it },
serverId = currentServer
)
}
}
}
}
}
@Composable
fun ColumnScope.DirectMessagesChannelListRenderer(
private fun ColumnScope.DirectMessagesChannelListRenderer(
currentDestination: ChatRouterDestination,
onDestinationChanged: (ChatRouterDestination) -> Unit,
channelListState: LazyListState,
@ -726,8 +695,9 @@ fun ColumnScope.DirectMessagesChannelListRenderer(
}
}
@Composable
fun ColumnScope.ServerChannelListRenderer(
private fun ColumnScope.ServerChannelListRenderer(
categorisedChannels: List<CategorisedChannelList>?,
currentDestination: ChatRouterDestination,
onDestinationChanged: (ChatRouterDestination) -> Unit,

View File

@ -0,0 +1,26 @@
package chat.revolt.di
import chat.revolt.api.routes.googlesheets.ServerDataRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
/**
* Dagger Hilt module for providing Google Sheets related dependencies
*/
@Module
@InstallIn(SingletonComponent::class)
object GoogleSheetsModule {
/**
* Provides a singleton instance of ServerDataRepository
* @return ServerDataRepository instance
*/
@Provides
@Singleton
fun provideServerDataRepository(): ServerDataRepository {
return ServerDataRepository()
}
}

View File

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material.icons.Icons
@ -24,7 +25,6 @@ import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.DrawerState
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@ -108,24 +108,13 @@ sealed class ChatRouterDestination {
data object Settings : ChatRouterDestination()
data object Friends : ChatRouterDestination()
data object Home : ChatRouterDestination()
data object Discover : ChatRouterDestination()
data class Channel(val channelId: String) : ChatRouterDestination()
data class ServersChannels(val serverID: String) : ChatRouterDestination()
data class NoCurrentChannel(val serverId: String?) : ChatRouterDestination()
fun asSerialisedString(): String {
return when (this) {
is Settings -> "overview"
is Friends -> "friends"
is Channel -> "channel/$channelId"
is ServersChannels -> "channel/$serverID/servers"
is NoCurrentChannel -> "no_current_channel/$serverId"
ChatRouterDestination.Home -> "home"
}
}
companion object {
val default = Settings
val defaultForDMList = Settings
fun fromString(destination: String): ChatRouterDestination {
return when {
@ -198,17 +187,6 @@ class ChatRouterViewModel @Inject constructor(
fun setSaveDestination(destination: ChatRouterDestination) {
currentDestination = destination
viewModelScope.launch {
kvStorage.set("currentDestination", destination.asSerialisedString())
if (destination is ChatRouterDestination.Channel) {
val server = RevoltAPI.channelCache[destination.channelId]?.server
if (server != null) {
kvStorage.set("lastChannel/$server", destination.channelId)
}
}
}
}
fun setRegisterForNotifications() {
@ -253,13 +231,7 @@ class ChatRouterViewModel @Inject constructor(
fun navigateToServer(serverId: String) {
viewModelScope.launch {
val savedLastChannel = kvStorage.get("lastChannel/$serverId")
val channelId =
savedLastChannel ?: RevoltAPI.serverCache[serverId]?.channels?.firstOrNull()
val channelExists = RevoltAPI.channelCache.containsKey(channelId)
setSaveDestination(ChatRouterDestination.ServersChannels(serverId))
//
setSaveDestination(ChatRouterDestination.ServersChannels(serverId))
}
}
}
@ -409,7 +381,11 @@ fun ChatRouterScreen(
return@let
}
viewModel.setSaveDestination(ChatRouterDestination.Channel(action.channelId))
viewModel.setSaveDestination(
ChatRouterDestination.Channel(
action.channelId
)
)
}
is Action.LinkInfo -> {
@ -818,14 +794,14 @@ fun ChatRouterScreen(
toggleDrawerLambda()
},
onShowStatusSheet = {
showStatusSheet = true
showStatusSheet = true
},
onShowServerContextSheet = {
serverContextSheetTarget = it
showServerContextSheet = true
serverContextSheetTarget = it
showServerContextSheet = true
},
onShowAddServerSheet = {
showAddServerSheet = true
showAddServerSheet = true
},
isTouchExplorationEnabled = isTouchExplorationEnabled,
viewModel = viewModel,
@ -835,32 +811,6 @@ fun ChatRouterScreen(
}
}
@Composable
fun Sidebar(
viewModel: ChatRouterViewModel,
currentServer: String?,
topNav: NavController,
onShowStatusSheet: () -> Unit,
navigateToServer: (String) -> Unit,
onShowServerContextSheet: (String) -> Unit,
onShowAddServerSheet: () -> Unit,
showSettingsButton: Boolean,
onOpenSettings: () -> Unit,
) {
ChannelSideDrawer(
onDestinationChanged = viewModel::setSaveDestination,
currentDestination = viewModel.currentDestination,
currentServer = currentServer,
navigateToServer = navigateToServer,
onLongPressAvatar = onShowStatusSheet,
onShowServerContextSheet = onShowServerContextSheet,
showSettingsIcon = showSettingsButton,
onOpenSettings = onOpenSettings,
topNav = topNav,
onShowAddServerSheet = onShowAddServerSheet
)
}
@Composable
fun ChannelNavigator(
dest: ChatRouterDestination,
@ -872,138 +822,132 @@ fun ChannelNavigator(
currentServer: String?,
toggleDrawer: () -> Unit,
isTouchExplorationEnabled: Boolean,
drawerState: DrawerState? = null,
setDrawerGestureEnabled: (Boolean) -> Unit = {},
) {
val scope = rememberCoroutineScope()
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
BottomAppBar {
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = "Home",
when (dest) {
is ChatRouterDestination.Channel -> {
ChannelScreen(
channelId = dest.channelId,
backToChannelsScreen = {
currentServer?.let {
viewModel.setSaveDestination(
ChatRouterDestination.ServersChannels(
serverID = currentServer
)
)
},
label = {
Text(text = "you")
},
selected = dest is ChatRouterDestination.Home,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Home)
}
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Person,
contentDescription = "Friends",
)
},
label = {
Text(text = "Friends")
},
selected = dest is ChatRouterDestination.Friends,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Friends)
}
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Face,
contentDescription = "You",
)
},
label = {
Text(text = "you")
},
selected = dest is ChatRouterDestination.Settings,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Settings)
}
)
}
} ?: viewModel.setSaveDestination(
ChatRouterDestination.Home
)
},
setDrawerGestureEnabled = setDrawerGestureEnabled,
)
}
) { innerPadding ->
Column {
when (dest) {
is ChatRouterDestination.Settings -> {
SettingsScreen(
navController = topNav,
)
}
is ChatRouterDestination.Friends -> {
FriendsScreen(
topNav = topNav,
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.Home -> {
Sidebar(
viewModel = viewModel,
topNav = topNav,
currentServer = currentServer,
onShowStatusSheet = onShowStatusSheet,
navigateToServer = viewModel::navigateToServer,
onShowServerContextSheet = onShowServerContextSheet,
onShowAddServerSheet = onShowAddServerSheet,
showSettingsButton = isTouchExplorationEnabled,
onOpenSettings = {
topNav.navigate("settings")
},
)
}
is ChatRouterDestination.ServersChannels-> {
Sidebar(
viewModel = viewModel,
topNav = topNav,
currentServer = dest.serverID,
onShowStatusSheet = onShowStatusSheet,
navigateToServer = viewModel::navigateToServer,
onShowServerContextSheet = onShowServerContextSheet,
onShowAddServerSheet = onShowAddServerSheet,
showSettingsButton = isTouchExplorationEnabled,
onOpenSettings = {
topNav.navigate("settings")
},
)
}
is ChatRouterDestination.Channel -> {
ChannelScreen(
channelId = dest.channelId,
backToChannelsScreen = {
currentServer?.let {
viewModel.setSaveDestination(ChatRouterDestination.ServersChannels(
serverID = currentServer
))
else -> {
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = {
BottomAppBar {
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Home,
contentDescription = "Home",
)
},
label = {
Text(text = "you")
},
selected = when(dest){
is ChatRouterDestination.ServersChannels,
is ChatRouterDestination.NoCurrentChannel,
ChatRouterDestination.Home,
ChatRouterDestination.Discover -> true
else -> false
} ,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Home)
}
},
onToggleDrawer = {
scope.launch {
if (drawerState?.isOpen == true) {
drawerState.close()
} else {
drawerState?.open()
}
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Person,
contentDescription = "Friends",
)
},
label = {
Text(text = "Friends")
},
selected = dest is ChatRouterDestination.Friends,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Friends)
}
},
setDrawerGestureEnabled = setDrawerGestureEnabled,
drawerIsOpen = drawerState?.isOpen == true,
)
)
NavigationBarItem(
icon = {
Icon(
imageVector = Icons.Default.Face,
contentDescription = "You",
)
},
label = {
Text(text = "you")
},
selected = dest is ChatRouterDestination.Settings,
enabled = true,
onClick = {
viewModel.setSaveDestination(ChatRouterDestination.Settings)
}
)
}
}
) { innerPadding ->
Column(modifier = Modifier.padding(innerPadding)) {
when (dest) {
is ChatRouterDestination.Settings -> {
SettingsScreen(
navController = topNav,
)
}
is ChatRouterDestination.NoCurrentChannel -> {
NoCurrentChannelScreen(onDrawerClicked = toggleDrawer)
is ChatRouterDestination.Friends -> {
FriendsScreen(
topNav = topNav,
onDrawerClicked = toggleDrawer,
)
}
is ChatRouterDestination.Home,
is ChatRouterDestination.ServersChannels,
is ChatRouterDestination.Discover -> {
ChannelSideDrawer(
onDestinationChanged = viewModel::setSaveDestination,
currentDestination = viewModel.currentDestination,
currentServer = when (dest) {
is ChatRouterDestination.Home -> currentServer
is ChatRouterDestination.ServersChannels -> dest.serverID
else -> null
},
navigateToServer = viewModel::navigateToServer,
onLongPressAvatar = onShowStatusSheet,
onShowServerContextSheet = onShowServerContextSheet,
showSettingsIcon = isTouchExplorationEnabled,
onOpenSettings = {
topNav.navigate("settings")
},
onShowAddServerSheet = onShowAddServerSheet
)
}
is ChatRouterDestination.Channel -> {}
is ChatRouterDestination.NoCurrentChannel -> {
NoCurrentChannelScreen(onDrawerClicked = toggleDrawer)
}
}
}
}
}

View File

@ -4,7 +4,6 @@ import android.content.Context
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@ -12,14 +11,10 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
@ -100,7 +95,6 @@ import chat.revolt.composables.generic.CountableListHeader
import chat.revolt.composables.generic.UserAvatar
import chat.revolt.internals.extensions.zero
import chat.revolt.markdown.jbm.asHexString
import chat.revolt.screens.chat.LocalIsConnected
import io.github.g00fy2.quickie.QRResult
import io.github.g00fy2.quickie.ScanQRCode
import kotlinx.coroutines.Dispatchers
@ -474,72 +468,61 @@ fun FriendsScreen(topNav: NavController, useDrawer: Boolean = false, onDrawerCli
Scaffold(
topBar = {
Column {
AnimatedVisibility(LocalIsConnected.current) {
Spacer(
Modifier
.height(
WindowInsets.statusBars.asPaddingValues()
.calculateTopPadding()
)
TopAppBar(
title = {
Text(
text = stringResource(R.string.friends),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
TopAppBar(
title = {
Text(
text = stringResource(R.string.friends),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
navigationIcon = {
if (useDrawer) {
IconButton(onClick = {
onDrawerClicked()
}) {
Icon(
painter = painterResource(R.drawable.icn_menu_24dp),
contentDescription = stringResource(id = R.string.menu)
)
}
}
},
actions = {
},
navigationIcon = {
if (useDrawer) {
IconButton(onClick = {
overflowMenuShown = true
onDrawerClicked()
}) {
Icon(
painter = painterResource(R.drawable.icn_more_vert_24dp),
contentDescription = stringResource(R.string.menu)
painter = painterResource(R.drawable.icn_menu_24dp),
contentDescription = stringResource(id = R.string.menu)
)
}
DropdownMenu(
expanded = overflowMenuShown,
onDismissRequest = {
overflowMenuShown = false
}
) {
DropdownMenuItem(
text = {
Text(stringResource(R.string.friends_deny_all_incoming))
},
onClick = {
}
},
actions = {
IconButton(onClick = {
overflowMenuShown = true
}) {
Icon(
painter = painterResource(R.drawable.icn_more_vert_24dp),
contentDescription = stringResource(R.string.menu)
)
}
DropdownMenu(
expanded = overflowMenuShown,
onDismissRequest = {
overflowMenuShown = false
}
) {
DropdownMenuItem(
text = {
Text(stringResource(R.string.friends_deny_all_incoming))
},
onClick = {
scope.launch {
overflowMenuShown = false
}
with(Dispatchers.IO) {
scope.launch {
overflowMenuShown = false
}
with(Dispatchers.IO) {
scope.launch {
FriendRequests.getIncoming()
.forEach { it.id?.let { id -> unfriendUser(id) } }
}
FriendRequests.getIncoming()
.forEach { it.id?.let { id -> unfriendUser(id) } }
}
}
)
}
},
windowInsets = WindowInsets.zero
)
}
}
)
}
},
windowInsets = WindowInsets.zero
)
},
) { pv ->
Box(

View File

@ -189,12 +189,10 @@ private const val NOT_ENOUGH_SPACE_FOR_PANES_THRESHOLD = 500
@Composable
fun ChannelScreen(
channelId: String,
onToggleDrawer: () -> Unit,
useDrawer: Boolean = false,
backToChannelsScreen: (() -> Unit)?,
useBackButton: Boolean = false,
setDrawerGestureEnabled: (Boolean) -> Unit = {},
drawerIsOpen: Boolean = false,
backButtonAction: (() -> Unit)? = null,
useChatUI: Boolean = false,
viewModel: ChannelScreenViewModel = hiltViewModel()
@ -629,7 +627,9 @@ fun ChannelScreen(
windowInsets = if (useChatUI) WindowInsets.statusBars else WindowInsets.zero,
navigationIcon = {
if (useDrawer) {
IconButton(onClick = onToggleDrawer) {
IconButton(onClick = {
backToChannelsScreen?.invoke()
}) {
Icon(
painter = painterResource(R.drawable.icn_menu_24dp),
contentDescription = stringResource(id = R.string.menu)
@ -650,7 +650,7 @@ fun ChannelScreen(
}
) { pv ->
if (viewModel.showGeoGate) {
ChannelScreenGeoGate { onToggleDrawer() }
ChannelScreenGeoGate { backToChannelsScreen?.invoke() }
} else {
Crossfade(
targetState = viewModel.ageGateUnlocked,
@ -665,10 +665,11 @@ fun ChannelScreen(
}
},
onDeny = {
onToggleDrawer()
backToChannelsScreen?.invoke()
}
)
}
null -> {
Box(
contentAlignment = Alignment.Center,
@ -677,6 +678,7 @@ fun ChannelScreen(
CircularProgressIndicator(modifier = Modifier.size(48.dp))
}
}
true -> {
Column(
modifier = Modifier
@ -731,7 +733,6 @@ fun ChannelScreen(
RegularMessage(
item.message,
viewModel.channel,
drawerIsOpen = drawerIsOpen,
setDrawerGestureEnabled = {
setDrawerGestureEnabled(it)
},
@ -972,7 +973,11 @@ fun ChannelScreen(
ReplyManager(
replies = viewModel.draftReplyTo,
onToggleMention = {
scope.launch { viewModel.toggleMentionOnReply(it.id) }
scope.launch {
viewModel.toggleMentionOnReply(
it.id
)
}
},
onRemove = {
viewModel.draftReplyTo.remove(it)
@ -1027,7 +1032,9 @@ fun ChannelScreen(
trailingIcon = {
Icon(
painter = painterResource(R.drawable.icn_close_24dp),
contentDescription = stringResource(R.string.message_field_editing_message_cancel_alt),
contentDescription = stringResource(
R.string.message_field_editing_message_cancel_alt
),
tint = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.alpha(0.8f)
)
@ -1090,7 +1097,8 @@ fun ChannelScreen(
DropdownMenu(
expanded = viewModel.activePane == ChannelScreenActivePane.AttachmentPicker && notEnoughSpaceForPanes,
onDismissRequest = {
viewModel.activePane = ChannelScreenActivePane.None
viewModel.activePane =
ChannelScreenActivePane.None
}
) {
DropdownMenuItem(

View File

@ -10,12 +10,11 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.ListItem
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@ -65,22 +64,20 @@ fun SettingsScreen(
val context = LocalContext.current
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
Column(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
LargeTopAppBar(
scrollBehavior = scrollBehavior,
title = {
Text(
text = stringResource(R.string.settings),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
)
},
) { pv ->
Box(Modifier.padding(pv)) {
) {
TopAppBar(
scrollBehavior = scrollBehavior,
title = {
Text(
text = stringResource(R.string.settings),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
},
)
Box {
Column(
modifier = Modifier
.fillMaxSize()
@ -377,7 +374,6 @@ fun SettingsScreen(
}
},
modifier = Modifier
.padding(bottom =92.dp)
.testTag("settings_view_logout")
.clickable {
viewModel.logout()

View File

@ -0,0 +1,210 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="86dp"
android:height="83dp"
android:viewportWidth="86"
android:viewportHeight="83">
<path
android:pathData="M54.223,3.968C55.642,2.891 57.614,2.589 59.291,3.193C60.591,3.66 61.802,4.643 63.174,4.482C64.094,4.374 64.862,3.765 65.669,3.312C66.476,2.858 67.52,2.559 68.296,3.064C68.896,3.453 69.15,4.258 68.989,4.954C68.829,5.65 68.309,6.229 67.684,6.575C68.449,6.526 69.113,7.318 69.034,8.081C68.955,8.844 68.253,9.458 67.492,9.554C67.872,9.842 68.003,10.381 67.893,10.845C67.784,11.309 67.472,11.703 67.109,12.012C65.888,13.053 64.076,13.222 62.564,12.687C61.052,12.152 59.821,10.998 58.913,9.676C58.813,9.531 58.715,9.38 58.669,9.21"
android:fillColor="#3B1954"/>
<path
android:pathData="M54.338,4.163C55.323,3.424 56.545,3.058 57.774,3.119C58.385,3.149 58.981,3.294 59.543,3.533C60.139,3.786 60.703,4.108 61.3,4.359C61.856,4.592 62.455,4.764 63.064,4.719C63.712,4.67 64.299,4.392 64.852,4.066C65.394,3.747 65.915,3.377 66.517,3.177C67.071,2.994 67.722,2.927 68.223,3.286C68.712,3.637 68.901,4.321 68.771,4.893C68.622,5.544 68.138,6.057 67.569,6.378C67.377,6.487 67.457,6.811 67.684,6.801C68.344,6.774 68.882,7.439 68.807,8.08C68.727,8.766 68.078,9.243 67.432,9.334C67.27,9.357 67.206,9.613 67.332,9.714C67.625,9.947 67.745,10.318 67.694,10.687C67.638,11.083 67.392,11.429 67.112,11.702C66.551,12.249 65.807,12.57 65.041,12.698C63.451,12.962 61.873,12.339 60.673,11.315C60.325,11.018 60.004,10.691 59.707,10.343C59.554,10.162 59.407,9.976 59.268,9.784C59.125,9.587 58.961,9.383 58.888,9.148C58.801,8.87 58.363,8.989 58.45,9.269C58.587,9.709 58.926,10.097 59.211,10.452C59.503,10.816 59.822,11.16 60.167,11.473C60.842,12.086 61.618,12.587 62.478,12.896C64.114,13.484 66.151,13.274 67.433,12.023C67.805,11.66 68.095,11.198 68.15,10.673C68.199,10.202 68.03,9.693 67.653,9.392L67.553,9.772C68.418,9.65 69.21,8.931 69.265,8.032C69.318,7.167 68.568,6.31 67.684,6.347L67.799,6.77C68.89,6.154 69.623,4.869 69.071,3.643C68.813,3.071 68.287,2.683 67.668,2.596C67.005,2.503 66.335,2.714 65.749,3.011C65.14,3.319 64.595,3.74 63.97,4.019C63.348,4.297 62.701,4.333 62.047,4.146C61.394,3.959 60.798,3.621 60.187,3.33C59.582,3.04 58.963,2.808 58.295,2.715C56.831,2.512 55.295,2.88 54.108,3.77C53.877,3.944 54.104,4.338 54.338,4.163Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M66.448,78.29C63.876,78.278 61.304,78.27 58.732,78.261C52.682,78.241 46.632,78.225 40.582,78.206C37.861,78.198 35.139,78.189 32.418,78.179C31.285,78.175 30.056,78.298 28.942,78.122C27.7,77.926 26.366,77.499 25.304,76.812C24.511,76.298 23.435,75.896 22.831,75.155C22.05,74.198 22.097,72.697 22.855,71.721C23.613,70.745 24.971,70.319 26.18,70.576C28.17,71 29.729,72.646 31.839,72.695C37.71,72.831 43.596,72.735 49.469,72.753C55.129,72.771 60.788,72.786 66.448,72.812C68.371,72.821 70.448,73.023 72.348,72.719C74.121,72.436 75.474,71.893 77.021,70.966C78.091,70.325 79.296,69.687 80.574,69.666C81.694,69.648 82.637,70.679 82.98,71.694C83.867,74.317 81.201,76.208 79.107,77.096C75.194,78.756 70.6,78.309 66.448,78.29Z"
android:fillColor="#FFDE17"/>
<path
android:pathData="M66.448,78.063C61.793,78.041 57.138,78.028 52.482,78.014C47.815,78 43.148,77.987 38.481,77.973C36.165,77.965 33.841,77.902 31.526,77.967C30.439,77.997 29.377,78.009 28.309,77.771C27.308,77.548 26.332,77.19 25.462,76.642C24.716,76.172 23.84,75.84 23.2,75.219C22.564,74.602 22.363,73.67 22.575,72.823C22.798,71.932 23.471,71.247 24.326,70.934C25.185,70.619 26.058,70.713 26.901,71.025C28.553,71.635 29.965,72.849 31.793,72.92C34.123,73.01 36.463,72.993 38.795,72.996C43.449,73.001 48.103,72.976 52.758,72.99C57.394,73.004 62.031,72.987 66.667,73.04C68.812,73.065 70.962,73.261 73.081,72.814C74.015,72.617 74.918,72.306 75.78,71.896C76.693,71.461 77.526,70.88 78.442,70.451C79.297,70.051 80.469,69.627 81.378,70.084C82.178,70.487 82.716,71.344 82.881,72.207C83.191,73.828 81.953,75.154 80.707,75.983C77.419,78.172 73.218,78.185 69.416,78.114C68.427,78.095 67.438,78.068 66.448,78.063C66.156,78.061 66.156,78.515 66.448,78.517C70.628,78.539 75.056,78.999 79.023,77.375C80.45,76.79 81.915,75.927 82.783,74.613C83.707,73.212 83.508,71.368 82.295,70.193C81.597,69.518 80.767,69.348 79.83,69.515C78.794,69.7 77.846,70.211 76.952,70.743C76.064,71.271 75.146,71.739 74.161,72.058C73.131,72.391 72.059,72.574 70.979,72.631C69.837,72.692 68.693,72.638 67.551,72.605C66.387,72.572 65.222,72.579 64.057,72.574C61.626,72.564 59.194,72.556 56.763,72.548C51.933,72.533 47.104,72.523 42.274,72.537C39.835,72.544 37.396,72.547 34.956,72.52C34.357,72.513 33.757,72.505 33.158,72.494C32.598,72.484 32.025,72.506 31.468,72.442C30.525,72.334 29.664,71.889 28.838,71.452C28.035,71.028 27.222,70.582 26.33,70.377C25.476,70.179 24.573,70.281 23.788,70.675C22.244,71.451 21.524,73.463 22.439,74.989C22.909,75.774 23.759,76.201 24.534,76.625C24.948,76.852 25.339,77.118 25.757,77.337C26.217,77.578 26.7,77.775 27.193,77.937C28.192,78.263 29.225,78.436 30.276,78.444C31.45,78.452 32.625,78.407 33.799,78.411C38.665,78.428 43.53,78.442 48.395,78.456C53.246,78.47 58.096,78.484 62.946,78.502C64.114,78.507 65.281,78.511 66.448,78.517C66.741,78.518 66.741,78.064 66.448,78.063Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M47.191,36.839C51.506,46.015 53.742,65.871 54.429,73.668C54.606,75.67 55.642,76.162 57.504,76.396C60.257,76.741 63.039,76.618 65.798,76.421C66.799,76.349 67.8,76.307 68.433,75.388C69.044,74.5 68.545,73.287 67.868,72.593C67.149,71.856 66.19,71.397 65.429,70.702C62.911,68.399 62.83,64.69 62.658,61.537C62.31,55.177 61.261,48.77 59.96,42.552C59.139,38.623 58.165,34.646 56.08,31.215"
android:fillColor="#FFDE17"/>
<path
android:pathData="M46.996,36.953C48.104,39.315 48.876,41.833 49.548,44.349C50.339,47.314 50.968,50.322 51.518,53.341C52.076,56.406 52.549,59.487 52.964,62.575C53.318,65.21 53.629,67.85 53.9,70.494C54.003,71.505 54.101,72.516 54.191,73.528C54.247,74.161 54.348,74.815 54.713,75.353C55.036,75.829 55.514,76.135 56.052,76.322C56.794,76.581 57.608,76.647 58.384,76.718C59.47,76.816 60.56,76.849 61.65,76.839C62.755,76.829 63.859,76.776 64.962,76.705C65.796,76.651 66.728,76.677 67.519,76.372C68.276,76.08 68.876,75.426 68.933,74.594C68.988,73.797 68.571,72.992 68.03,72.433C67.38,71.76 66.536,71.329 65.819,70.738C65.174,70.207 64.65,69.548 64.253,68.814C63.467,67.361 63.189,65.686 63.045,64.059C62.877,62.165 62.826,60.263 62.657,58.369C62.27,54.025 61.598,49.709 60.772,45.428C60.004,41.45 59.237,37.386 57.6,33.657C57.213,32.777 56.774,31.922 56.277,31.1C56.126,30.851 55.733,31.079 55.885,31.33C57.93,34.71 58.896,38.586 59.701,42.416C60.591,46.646 61.356,50.907 61.871,55.2C62.126,57.327 62.319,59.462 62.435,61.601C62.522,63.207 62.588,64.824 62.925,66.401C63.258,67.96 63.893,69.476 65.025,70.626C65.666,71.277 66.462,71.719 67.175,72.28C67.821,72.786 68.419,73.479 68.478,74.337C68.539,75.21 67.873,75.833 67.075,76.036C66.7,76.131 66.314,76.157 65.93,76.185C65.416,76.221 64.903,76.256 64.389,76.286C62.243,76.411 60.085,76.451 57.945,76.22C56.748,76.091 55.297,75.912 54.846,74.604C54.662,74.07 54.643,73.501 54.592,72.944C54.547,72.452 54.5,71.961 54.452,71.47C54.206,68.969 53.922,66.472 53.602,63.98C53.22,60.995 52.786,58.015 52.278,55.049C51.761,52.023 51.172,49.008 50.444,46.025C49.803,43.398 49.067,40.778 48.057,38.266C47.848,37.746 47.626,37.231 47.389,36.724C47.265,36.46 46.873,36.69 46.996,36.953Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M54.429,73.667C54.605,75.67 55.642,76.162 57.504,76.395C60.256,76.741 63.039,76.618 65.798,76.42C66.799,76.349 67.8,76.306 68.432,75.387C69.043,74.499 68.545,73.287 67.868,72.592C67.148,71.855 66.189,71.396 65.429,70.701C64.978,70.288 64.592,69.832 64.341,69.272C64.092,68.717 64.004,68.062 63.563,67.61C62.939,66.971 61.8,67.082 61.142,67.687C60.736,68.06 60.489,68.573 60.369,69.106C60.309,69.372 60.281,69.644 60.276,69.917C60.273,70.098 60.309,70.501 60.162,70.633C60.12,70.671 60.065,70.689 60.011,70.704C59.564,70.831 59.094,70.844 58.629,70.85C57.381,70.868 56.139,70.943 54.905,71C54.06,71.04 54.377,73.088 54.429,73.667Z"
android:fillColor="#FFDE17"/>
<path
android:pathData="M54.203,73.668C54.254,74.217 54.362,74.777 54.65,75.255C54.886,75.647 55.236,75.954 55.646,76.154C56.11,76.381 56.619,76.494 57.127,76.571C57.942,76.695 58.768,76.761 59.591,76.801C61.357,76.887 63.127,76.822 64.89,76.71C66.2,76.626 67.855,76.713 68.659,75.459C69.027,74.884 68.993,74.156 68.748,73.541C68.479,72.87 68.005,72.354 67.441,71.915C66.834,71.443 66.16,71.06 65.591,70.541C65.044,70.042 64.633,69.472 64.393,68.769C64.178,68.141 63.947,67.463 63.309,67.146C62.74,66.864 62.064,66.911 61.499,67.177C60.862,67.478 60.441,68.1 60.231,68.755C60.111,69.128 60.055,69.526 60.051,69.917C60.049,70.043 60.058,70.169 60.047,70.294C60.043,70.338 60.046,70.424 60.015,70.458C59.974,70.505 59.825,70.519 59.768,70.531C59.361,70.619 58.942,70.618 58.529,70.625C58.087,70.633 57.645,70.647 57.204,70.665C56.753,70.683 56.301,70.705 55.85,70.728C55.648,70.738 55.446,70.748 55.243,70.758C55.082,70.765 54.905,70.753 54.748,70.797C54.324,70.915 54.186,71.379 54.135,71.766C54.074,72.236 54.107,72.715 54.153,73.185C54.169,73.346 54.188,73.507 54.203,73.668C54.229,73.957 54.683,73.959 54.657,73.668C54.624,73.297 54.576,72.929 54.562,72.557C54.548,72.189 54.524,71.713 54.703,71.388C54.729,71.34 54.777,71.284 54.796,71.269C54.854,71.224 54.903,71.228 55.008,71.223C55.424,71.203 55.84,71.182 56.256,71.162C57.09,71.121 57.923,71.092 58.757,71.076C59.136,71.069 59.517,71.05 59.888,70.969C60.048,70.935 60.231,70.897 60.346,70.771C60.441,70.667 60.474,70.525 60.492,70.39C60.529,70.087 60.496,69.781 60.534,69.478C60.578,69.133 60.674,68.786 60.833,68.476C61.118,67.922 61.604,67.508 62.233,67.422C62.825,67.341 63.358,67.581 63.648,68.109C63.808,68.402 63.895,68.728 64.007,69.04C64.12,69.354 64.263,69.654 64.451,69.93C64.849,70.519 65.38,70.993 65.952,71.409C66.977,72.153 68.383,72.91 68.478,74.34C68.521,74.975 68.17,75.527 67.619,75.83C67.106,76.111 66.495,76.144 65.924,76.185C64.288,76.301 62.649,76.397 61.008,76.385C60.175,76.379 59.343,76.346 58.513,76.275C57.869,76.219 57.216,76.16 56.586,76.005C56.182,75.906 55.77,75.762 55.445,75.493C55.118,75.223 54.914,74.854 54.797,74.45C54.724,74.195 54.682,73.932 54.657,73.668C54.631,73.379 54.176,73.377 54.203,73.668Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M55.124,74.45C54.979,74.441 54.769,74.407 54.543,74.381C54.892,75.795 55.886,76.193 57.504,76.396C60.256,76.742 63.039,76.619 65.798,76.421C66.799,76.35 67.8,76.307 68.432,75.388C69.043,74.5 68.545,73.288 67.868,72.594C67.352,72.064 66.712,71.678 66.111,71.246C65.839,71.542 65.653,71.926 65.515,72.309C65.384,72.672 65.286,73.047 65.22,73.427C65.169,73.721 65.136,74.026 64.998,74.291C64.782,74.706 64.338,74.807 63.908,74.834C61.01,75.02 58.015,74.631 55.124,74.45Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M55.122,74.222C54.928,74.207 54.735,74.176 54.542,74.153C54.39,74.135 54.29,74.312 54.323,74.441C54.449,74.938 54.678,75.416 55.065,75.764C55.443,76.105 55.921,76.304 56.409,76.429C57.093,76.605 57.809,76.668 58.51,76.729C59.362,76.802 60.218,76.835 61.073,76.84C62.749,76.849 64.425,76.752 66.096,76.626C66.709,76.58 67.345,76.512 67.887,76.198C68.455,75.869 68.866,75.296 68.927,74.637C68.994,73.903 68.648,73.166 68.189,72.613C67.654,71.967 66.899,71.532 66.225,71.049C66.147,70.994 66.012,71.015 65.949,71.085C65.397,71.702 65.139,72.564 65,73.366C64.938,73.719 64.918,74.184 64.599,74.413C64.329,74.607 63.96,74.605 63.643,74.622C61.819,74.717 59.992,74.596 58.174,74.454C57.157,74.374 56.141,74.286 55.122,74.222C54.83,74.203 54.832,74.658 55.122,74.676C56.988,74.794 58.848,74.991 60.716,75.073C61.647,75.113 62.58,75.126 63.511,75.082C63.891,75.065 64.286,75.06 64.641,74.905C64.991,74.753 65.205,74.462 65.315,74.102C65.382,73.881 65.408,73.65 65.449,73.423C65.495,73.17 65.556,72.92 65.631,72.674C65.77,72.22 65.951,71.763 66.271,71.406L65.995,71.441C67.002,72.163 68.316,72.894 68.469,74.265C68.536,74.863 68.26,75.413 67.759,75.743C67.29,76.053 66.718,76.123 66.171,76.166C64.633,76.288 63.089,76.375 61.546,76.385C60.043,76.395 58.504,76.358 57.021,76.096C56.503,76.005 55.974,75.871 55.538,75.565C55.117,75.269 54.885,74.809 54.761,74.32L54.542,74.607C54.735,74.63 54.928,74.661 55.122,74.676C55.414,74.698 55.412,74.244 55.122,74.222Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M40.816,50.791C40.567,53.782 40.288,56.873 38.851,59.508C37.56,61.873 35.554,64.022 33.933,66.179C32.558,68.011 31.159,69.826 29.732,71.619C28.48,73.191 28.892,74.262 30.079,75.715C31.835,77.862 33.936,79.691 36.071,81.45C36.846,82.088 37.6,82.747 38.691,82.518C39.746,82.295 40.221,81.074 40.209,80.104C40.196,79.074 39.818,78.08 39.746,77.052C39.509,73.648 42.007,70.905 44.055,68.503C46.223,65.959 48.924,63.384 49.979,60.11C50.567,58.284 50.617,56.324 50.447,54.413"
android:fillColor="#FFDE17"/>
<path
android:pathData="M40.586,50.79C40.381,53.242 40.166,55.742 39.271,58.056C38.37,60.383 36.703,62.335 35.156,64.254C33.481,66.331 31.91,68.49 30.259,70.586C29.572,71.457 28.637,72.395 28.747,73.6C28.85,74.719 29.7,75.643 30.403,76.452C32.079,78.383 34.022,80.055 35.99,81.678C36.406,82.021 36.828,82.375 37.328,82.59C37.821,82.802 38.384,82.86 38.901,82.695C39.8,82.41 40.278,81.478 40.399,80.597C40.569,79.359 40.028,78.166 39.963,76.941C39.907,75.864 40.138,74.796 40.564,73.809C41.428,71.808 42.931,70.152 44.336,68.518C45.828,66.782 47.442,65.134 48.701,63.211C49.321,62.264 49.847,61.249 50.195,60.169C50.593,58.934 50.748,57.627 50.756,56.333C50.76,55.692 50.727,55.051 50.671,54.412C50.646,54.124 50.191,54.121 50.217,54.412C50.328,55.686 50.352,56.979 50.168,58.248C49.998,59.431 49.64,60.57 49.096,61.634C48.069,63.645 46.542,65.339 45.053,67.015C44.338,67.82 43.634,68.633 42.941,69.457C42.249,70.281 41.575,71.125 40.999,72.036C40.43,72.935 39.955,73.911 39.703,74.949C39.577,75.466 39.506,76 39.5,76.532C39.494,77.148 39.593,77.751 39.718,78.352C39.929,79.371 40.183,80.463 39.672,81.437C39.479,81.803 39.184,82.128 38.78,82.257C38.282,82.416 37.758,82.322 37.306,82.077C36.832,81.819 36.424,81.451 36.01,81.108C35.525,80.707 35.043,80.302 34.567,79.891C33.615,79.067 32.686,78.216 31.81,77.312C31.372,76.86 30.947,76.396 30.539,75.916C30.161,75.471 29.783,75.016 29.504,74.5C29.288,74.101 29.15,73.657 29.205,73.199C29.269,72.658 29.579,72.171 29.91,71.752C30.745,70.698 31.575,69.64 32.395,68.574C33.19,67.538 33.962,66.483 34.771,65.458C36.28,63.547 37.932,61.701 39.087,59.542C40.234,57.398 40.637,54.966 40.88,52.574C40.94,51.98 40.99,51.385 41.04,50.79C41.064,50.499 40.61,50.5 40.586,50.79Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M29.732,71.619C28.48,73.192 28.892,74.263 30.079,75.715C31.835,77.863 33.936,79.692 36.071,81.451C36.846,82.089 37.6,82.748 38.691,82.518C39.746,82.296 40.221,81.074 40.209,80.104C40.196,79.074 39.818,78.081 39.746,77.053C39.703,76.443 39.739,75.847 39.943,75.268C40.145,74.694 40.533,74.159 40.525,73.528C40.513,72.635 39.611,71.93 38.718,71.914C38.166,71.905 37.634,72.106 37.18,72.41C36.953,72.561 36.745,72.739 36.554,72.933C36.427,73.062 36.174,73.379 35.977,73.373C35.921,73.372 35.868,73.347 35.818,73.321C35.407,73.104 35.058,72.79 34.717,72.474C33.8,71.627 32.849,70.825 31.916,70.016C31.276,69.462 30.094,71.165 29.732,71.619Z"
android:fillColor="#FFDE17"/>
<path
android:pathData="M29.572,71.458C29.147,71.998 28.782,72.609 28.745,73.313C28.714,73.909 28.949,74.481 29.26,74.978C29.666,75.629 30.187,76.214 30.698,76.784C31.223,77.369 31.773,77.932 32.339,78.477C33.473,79.569 34.672,80.59 35.886,81.591C36.391,82.007 36.9,82.45 37.527,82.668C38.118,82.873 38.838,82.835 39.364,82.475C39.823,82.161 40.12,81.668 40.284,81.143C40.481,80.511 40.454,79.86 40.351,79.213C40.225,78.418 39.992,77.642 39.962,76.832C39.948,76.449 39.968,76.064 40.057,75.689C40.143,75.327 40.301,75 40.453,74.662C40.73,74.046 40.888,73.393 40.549,72.766C40.262,72.235 39.699,71.852 39.113,71.732C38.4,71.587 37.66,71.816 37.066,72.213C36.787,72.399 36.535,72.62 36.306,72.865C36.233,72.944 36.127,73.095 36.019,73.128C35.903,73.163 35.721,73.003 35.624,72.936C35.3,72.716 35.018,72.441 34.73,72.177C34.419,71.892 34.103,71.611 33.785,71.332C33.476,71.062 33.166,70.794 32.855,70.526C32.704,70.396 32.553,70.266 32.403,70.136C32.268,70.02 32.137,69.884 31.988,69.786C31.608,69.537 31.167,69.773 30.854,70.018C30.481,70.311 30.174,70.684 29.883,71.056C29.778,71.19 29.656,71.352 29.572,71.458C29.392,71.685 29.711,72.009 29.893,71.78C30.131,71.48 30.356,71.172 30.61,70.886C30.855,70.611 31.161,70.248 31.531,70.147C31.59,70.131 31.635,70.128 31.676,70.138C31.757,70.159 31.822,70.233 31.906,70.306C32.207,70.566 32.509,70.826 32.811,71.086C33.4,71.594 33.985,72.107 34.557,72.634C34.823,72.88 35.094,73.124 35.394,73.328C35.645,73.499 35.929,73.692 36.23,73.53C36.473,73.4 36.642,73.157 36.84,72.971C37.089,72.736 37.368,72.536 37.676,72.385C38.243,72.108 38.912,72.04 39.481,72.344C39.963,72.602 40.331,73.075 40.296,73.641C40.276,73.965 40.136,74.271 40.002,74.561C39.859,74.87 39.718,75.177 39.634,75.508C39.451,76.231 39.481,76.99 39.601,77.72C39.802,78.945 40.3,80.275 39.665,81.457C39.422,81.91 39.036,82.246 38.516,82.32C37.895,82.409 37.343,82.141 36.854,81.785C36.293,81.378 35.77,80.91 35.241,80.464C34.672,79.983 34.108,79.495 33.557,78.994C32.471,78.007 31.428,76.968 30.482,75.845C30.059,75.344 29.613,74.815 29.362,74.201C29.157,73.696 29.147,73.17 29.353,72.663C29.483,72.344 29.681,72.049 29.893,71.78C30.072,71.552 29.753,71.229 29.572,71.458Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M29.696,72.663C29.597,72.556 29.469,72.387 29.323,72.213C28.601,73.478 29.047,74.452 30.079,75.713C31.835,77.861 33.935,79.69 36.07,81.449C36.845,82.087 37.599,82.746 38.691,82.516C39.746,82.294 40.22,81.072 40.208,80.103C40.199,79.364 40.002,78.643 39.865,77.916C39.464,77.942 39.064,78.092 38.7,78.275C38.355,78.448 38.025,78.651 37.716,78.881C37.476,79.059 37.242,79.257 36.96,79.354C36.517,79.506 36.125,79.273 35.795,78.996C33.568,77.133 31.667,74.787 29.696,72.663Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M29.856,72.503C29.726,72.358 29.607,72.203 29.483,72.053C29.389,71.94 29.192,71.98 29.126,72.099C28.809,72.665 28.657,73.29 28.801,73.932C28.951,74.604 29.372,75.188 29.792,75.718C30.764,76.946 31.874,78.065 33.025,79.124C33.596,79.65 34.181,80.161 34.774,80.663C35.333,81.137 35.892,81.62 36.475,82.066C36.984,82.456 37.558,82.778 38.215,82.79C38.814,82.802 39.38,82.571 39.767,82.109C40.169,81.63 40.372,81.013 40.424,80.396C40.496,79.542 40.242,78.687 40.083,77.856C40.066,77.766 39.957,77.682 39.864,77.689C39.017,77.758 38.223,78.219 37.556,78.72C37.261,78.94 36.921,79.248 36.524,79.158C36.137,79.07 35.82,78.727 35.532,78.474C34.208,77.311 33.015,76.009 31.839,74.699C31.18,73.965 30.526,73.226 29.856,72.503C29.657,72.288 29.336,72.61 29.535,72.824C30.767,74.154 31.943,75.534 33.196,76.844C33.814,77.49 34.45,78.12 35.118,78.713C35.427,78.987 35.744,79.309 36.12,79.489C36.507,79.675 36.899,79.663 37.277,79.461C37.689,79.243 38.036,78.911 38.439,78.675C38.875,78.42 39.353,78.185 39.864,78.144L39.645,77.977C39.87,79.152 40.271,80.441 39.61,81.552C39.35,81.988 38.946,82.281 38.433,82.329C37.83,82.384 37.304,82.116 36.831,81.769C36.287,81.371 35.778,80.918 35.263,80.484C34.718,80.024 34.178,79.557 33.648,79.078C32.591,78.122 31.573,77.118 30.643,76.036C30.161,75.475 29.632,74.882 29.355,74.185C29.1,73.545 29.186,72.922 29.518,72.328L29.162,72.374C29.286,72.524 29.404,72.68 29.535,72.824C29.731,73.042 30.052,72.719 29.856,72.503Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M55.891,30.194C57.244,33.35 58.97,36.346 61.019,39.101C62.847,41.558 65.106,43.932 68.067,44.71C70.832,45.437 73.885,44.602 76.116,42.814C78.417,40.97 79.738,38.347 80.392,35.534C81.146,32.289 81.933,29.087 82.559,25.803C82.645,25.347 82.738,24.878 82.993,24.491C83.21,24.162 83.529,23.916 83.81,23.64C84.943,22.528 85.87,20.308 84.797,18.876C84.231,18.121 83.28,17.769 82.364,17.538C81.668,17.363 80.955,17.234 80.238,17.256C79.864,17.268 79.485,17.323 79.144,17.478C78.701,17.68 78.577,18.018 78.282,18.343C77.99,18.096 77.594,17.98 77.215,18.036C76.836,18.092 76.485,18.321 76.28,18.645C76.116,18.905 76.046,19.213 76,19.517C75.885,20.282 75.907,21.057 75.903,21.828C75.9,22.498 75.964,23.315 75.631,23.913C75.333,24.448 75.137,25.061 74.911,25.63C74.438,26.819 73.985,28.017 73.533,29.215C73.08,30.414 72.629,31.612 72.157,32.803C71.92,33.399 71.679,33.993 71.43,34.584C71.3,34.891 71.168,35.198 71.034,35.504C70.986,35.614 70.644,36.187 70.688,36.279C70.047,34.95 69.405,33.619 68.637,32.359C67.261,30.1 65.451,27.997 64.907,25.409"
android:fillColor="#FFDE17"/>
<path
android:pathData="M55.696,30.31C56.581,32.369 57.621,34.36 58.807,36.261C59.923,38.047 61.147,39.803 62.577,41.354C63.884,42.772 65.429,44.024 67.257,44.694C69.117,45.376 71.173,45.339 73.046,44.727C74.927,44.113 76.592,42.947 77.851,41.425C79.082,39.936 79.918,38.162 80.432,36.307C80.737,35.207 80.967,34.083 81.228,32.971C81.499,31.815 81.768,30.658 82.025,29.499C82.286,28.324 82.534,27.147 82.76,25.965C82.858,25.454 82.943,24.905 83.278,24.487C83.576,24.116 83.973,23.837 84.278,23.47C85.345,22.186 86.078,20.077 84.894,18.633C84.279,17.884 83.305,17.54 82.395,17.313C81.838,17.174 81.269,17.066 80.696,17.036C80.137,17.007 79.545,17.042 79.032,17.283C78.616,17.478 78.415,17.855 78.123,18.183H78.444C77.928,17.765 77.224,17.668 76.636,18.005C76.017,18.36 75.836,19.019 75.753,19.683C75.657,20.445 75.674,21.22 75.678,21.986C75.682,22.622 75.716,23.276 75.408,23.854C75.063,24.498 74.838,25.206 74.57,25.884C74.281,26.615 74,27.35 73.721,28.085C73.155,29.576 72.6,31.072 72.014,32.556C71.696,33.362 71.369,34.166 71.026,34.962C70.915,35.221 70.798,35.469 70.667,35.718C70.578,35.888 70.412,36.138 70.471,36.34L70.886,36.165C70.136,34.61 69.374,33.063 68.436,31.611C67.611,30.333 66.704,29.102 66.008,27.746C65.618,26.985 65.307,26.187 65.128,25.35C65.067,25.064 64.629,25.185 64.69,25.471C65.013,26.981 65.761,28.348 66.589,29.637C67.462,30.998 68.396,32.31 69.163,33.736C69.633,34.609 70.063,35.502 70.494,36.395C70.607,36.628 70.981,36.464 70.909,36.22C70.925,36.274 70.899,36.293 70.924,36.235C70.936,36.206 70.947,36.176 70.96,36.146C71.006,36.045 71.059,35.947 71.111,35.85C71.221,35.645 71.313,35.436 71.405,35.222C71.693,34.553 71.971,33.88 72.242,33.203C72.797,31.818 73.322,30.421 73.849,29.025C74.368,27.649 74.901,26.279 75.431,24.908C75.554,24.589 75.7,24.287 75.854,23.983C75.996,23.703 76.065,23.403 76.102,23.093C76.176,22.459 76.13,21.805 76.133,21.168C76.134,20.76 76.142,20.352 76.178,19.946C76.211,19.585 76.25,19.187 76.421,18.861C76.747,18.237 77.572,18.058 78.123,18.504C78.214,18.578 78.356,18.604 78.444,18.504C78.743,18.168 78.931,17.787 79.38,17.629C79.889,17.449 80.457,17.46 80.987,17.512C81.529,17.566 82.068,17.687 82.591,17.835C83.03,17.958 83.463,18.114 83.856,18.348C84.619,18.803 85.06,19.546 85.046,20.438C85.033,21.28 84.689,22.105 84.221,22.795C83.985,23.143 83.701,23.439 83.392,23.724C83.007,24.08 82.699,24.448 82.53,24.952C82.362,25.453 82.296,25.991 82.193,26.508C82.079,27.082 81.96,27.655 81.838,28.227C81.355,30.486 80.815,32.732 80.29,34.982C80.068,35.932 79.822,36.869 79.462,37.779C79.124,38.635 78.698,39.458 78.185,40.223C77.135,41.788 75.693,43.076 73.98,43.874C72.274,44.669 70.302,44.972 68.452,44.57C66.605,44.168 64.998,43.097 63.651,41.803C62.22,40.428 61.031,38.811 59.932,37.166C58.735,35.372 57.669,33.491 56.747,31.541C56.519,31.058 56.299,30.572 56.089,30.081C55.974,29.813 55.582,30.044 55.696,30.31Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M65.318,31.725C65.797,31.047 66.434,30.396 66.884,29.681C66.015,28.34 65.233,26.962 64.907,25.41L55.891,30.196C57.244,33.351 58.97,36.348 61.019,39.103C61.512,39.765 62.036,40.421 62.597,41.041C62.615,41.018 62.631,40.994 62.645,40.967C62.773,40.715 62.633,40.419 62.532,40.155C62.108,39.05 62.389,37.806 62.774,36.687C63.382,34.924 64.242,33.248 65.318,31.725Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M48.936,37.792C53.303,37.001 58.474,35.575 61.983,32.771C65.299,30.122 67.725,26.309 68.476,22.111C68.663,21.062 68.741,19.994 68.714,18.928C68.371,5.358 53.028,0.5 41.632,1.739C36.881,2.256 32.149,3.687 27.407,3.092C24.498,2.727 21.743,1.613 18.903,0.883C16.063,0.153 12.959,-0.172 10.272,1.002C8.17,1.921 5.703,4.697 7.746,6.894C6.748,6.647 5.732,6.421 4.704,6.446C3.676,6.471 2.623,6.772 1.862,7.464C0.804,8.426 0.484,10.042 0.887,11.414C1.29,12.786 2.328,13.912 3.557,14.643C2.7,14.288 1.665,14.797 1.182,15.59C0.699,16.382 0.664,17.371 0.789,18.291C0.992,19.796 1.626,21.226 2.55,22.427C3.244,23.331 4.493,25.225 5.62,25.52C4.37,25.39 3.351,26.743 3.411,27.999C3.47,29.254 4.289,30.344 5.189,31.222C7.531,33.507 10.59,34.919 13.699,35.942C19.313,37.789 25.332,38.3 31.211,38.349C37.178,38.398 42.965,38.874 48.936,37.792Z"
android:fillColor="#FFDE17"/>
<path
android:pathData="M48.995,38.012C52.734,37.331 56.526,36.342 59.858,34.464C63.098,32.638 65.744,29.758 67.33,26.396C68.909,23.049 69.353,19.251 68.54,15.636C67.94,12.966 66.609,10.516 64.739,8.522C62.868,6.528 60.524,5.014 58.032,3.914C55.422,2.761 52.638,2.03 49.813,1.646C46.995,1.263 44.132,1.218 41.306,1.549C36.778,2.08 32.259,3.402 27.665,2.896C23.279,2.413 19.269,0.183 14.827,0.011C12.935,-0.063 10.885,0.231 9.275,1.289C8.041,2.1 6.809,3.43 6.754,4.986C6.727,5.774 7.065,6.48 7.584,7.055L7.805,6.675C5.785,6.179 3.287,5.764 1.628,7.372C0.243,8.713 0.208,10.926 1.117,12.533C1.663,13.498 2.498,14.269 3.441,14.84L3.616,14.425C2.724,14.089 1.727,14.509 1.157,15.232C0.483,16.087 0.424,17.254 0.56,18.292C0.707,19.411 1.086,20.494 1.643,21.475C2.118,22.311 2.737,23.084 3.33,23.839C3.911,24.577 4.616,25.467 5.559,25.739L5.619,25.293C4.275,25.192 3.281,26.478 3.186,27.723C3.069,29.272 4.216,30.633 5.275,31.619C7.719,33.894 10.85,35.277 13.998,36.278C17.505,37.393 21.158,37.995 24.819,38.302C28.563,38.616 32.328,38.587 36.083,38.673C40.4,38.771 44.73,38.776 48.995,38.012C49.282,37.96 49.16,37.522 48.874,37.574C45.257,38.222 41.58,38.309 37.915,38.254C36.121,38.227 34.327,38.17 32.533,38.139C30.742,38.109 28.952,38.098 27.163,38.006C23.678,37.826 20.195,37.416 16.801,36.59C13.636,35.819 10.441,34.731 7.699,32.936C6.297,32.017 4.766,30.839 3.998,29.309C3.628,28.57 3.495,27.711 3.847,26.941C4.168,26.238 4.816,25.687 5.619,25.747C5.88,25.767 5.92,25.371 5.68,25.301C4.968,25.096 4.415,24.441 3.956,23.894C3.445,23.284 2.96,22.636 2.503,21.984C1.923,21.157 1.478,20.236 1.214,19.26C0.96,18.318 0.817,17.254 1.109,16.304C1.413,15.316 2.427,14.46 3.496,14.863C3.742,14.956 3.884,14.577 3.671,14.448C1.783,13.306 0.35,11.114 1.187,8.871C1.606,7.751 2.576,7.047 3.721,6.791C5.041,6.496 6.397,6.797 7.684,7.113C7.91,7.169 8.057,6.901 7.905,6.734C7.344,6.112 7.08,5.33 7.276,4.502C7.459,3.729 7.943,3.052 8.499,2.499C9.804,1.199 11.596,0.618 13.404,0.486C17.705,0.173 21.662,2.184 25.778,3.046C30.114,3.954 34.418,3.073 38.713,2.376C41.78,1.878 44.831,1.642 47.933,1.895C50.686,2.12 53.423,2.673 56.026,3.601C58.556,4.502 60.987,5.779 63.035,7.527C65.023,9.224 66.62,11.367 67.531,13.826C68.703,16.988 68.799,20.544 67.849,23.773C66.81,27.301 64.581,30.47 61.681,32.722C58.741,35.004 55.047,36.211 51.465,37.042C50.606,37.241 49.742,37.416 48.874,37.574C48.587,37.626 48.709,38.064 48.995,38.012Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M63.234,7.846C63.334,7.787 63.428,7.721 63.519,7.65C57.968,2.677 48.979,0.94 41.631,1.739C36.88,2.256 32.148,3.687 27.406,3.092C24.497,2.727 21.742,1.613 18.902,0.883C16.063,0.153 12.958,-0.172 10.271,1.002C8.17,1.921 5.702,4.697 7.745,6.894C6.747,6.647 5.731,6.421 4.703,6.446C3.676,6.471 2.622,6.772 1.861,7.464C1.734,7.579 1.618,7.705 1.512,7.839C1.39,8.291 1.281,8.747 1.185,9.202C1.047,9.863 0.93,10.529 0.83,11.196C0.847,11.27 0.865,11.342 0.886,11.414C1.289,12.786 2.328,13.912 3.556,14.643C2.699,14.288 1.664,14.797 1.181,15.59C0.698,16.382 0.663,17.371 0.788,18.291C0.991,19.796 1.625,21.226 2.549,22.427C3.244,23.331 4.492,25.225 5.62,25.52C4.369,25.39 3.351,26.743 3.41,27.999C3.469,29.254 4.288,30.344 5.188,31.222C7.53,33.507 10.589,34.919 13.698,35.942C15.259,36.455 16.853,36.863 18.465,37.188C20.008,35.962 21.507,34.681 22.832,33.226C25.357,30.452 27.189,27.118 29.598,24.243C32.972,20.215 37.476,17.144 42.458,15.475L41.986,15.773C43.987,14.836 46.942,13.94 49.136,13.679C48.319,13.212 48.207,11.945 48.81,11.223C49.414,10.5 50.514,10.328 51.398,10.653C52.281,10.977 52.962,11.714 53.424,12.534C54.894,11.896 55.845,10.231 55.649,8.641C56.443,9.384 57.497,10.033 58.56,9.803C59.623,9.573 60.294,8.015 59.433,7.35C60.398,8.332 62.049,8.547 63.234,7.846Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M63.348,8.043C63.446,7.981 63.539,7.917 63.632,7.847C63.742,7.765 63.798,7.597 63.678,7.49C60.853,4.972 57.323,3.357 53.684,2.407C49.963,1.437 46.045,1.112 42.215,1.455C37.456,1.88 32.759,3.377 27.943,2.924C23.284,2.486 19.038,0.005 14.308,0C12.337,-0.002 10.295,0.439 8.727,1.688C7.502,2.664 6.316,4.325 6.903,5.962C7.05,6.374 7.291,6.732 7.583,7.055L7.804,6.675C5.888,6.204 3.621,5.804 1.928,7.114C1.741,7.258 1.568,7.418 1.415,7.599C1.25,7.795 1.22,8.045 1.16,8.289C1.023,8.842 0.907,9.4 0.805,9.961C0.712,10.465 0.528,11.021 0.68,11.521C0.808,11.947 1,12.357 1.236,12.734C1.782,13.607 2.563,14.31 3.441,14.84L3.616,14.425C2.731,14.089 1.74,14.504 1.169,15.215C0.482,16.069 0.423,17.25 0.559,18.292C0.707,19.416 1.088,20.502 1.649,21.486C2.123,22.319 2.74,23.09 3.332,23.842C3.911,24.578 4.617,25.47 5.558,25.739L5.618,25.293C4.143,25.179 3.08,26.741 3.188,28.101C3.33,29.879 4.78,31.27 6.089,32.324C9.014,34.68 12.687,36.02 16.292,36.93C16.797,37.057 17.305,37.175 17.814,37.285C18.004,37.326 18.271,37.436 18.464,37.416C18.661,37.396 18.838,37.18 18.986,37.06C19.768,36.431 20.537,35.784 21.275,35.104C22.71,33.783 23.97,32.315 25.127,30.748C26.285,29.177 27.354,27.543 28.52,25.978C29.623,24.496 30.834,23.104 32.188,21.846C34.818,19.4 37.917,17.448 41.266,16.147C41.68,15.986 42.097,15.836 42.517,15.694L42.342,15.279L41.87,15.577C41.619,15.735 41.837,16.091 42.099,15.969C44.294,14.95 46.729,14.201 49.134,13.906C49.347,13.88 49.457,13.611 49.249,13.483C48.761,13.185 48.578,12.583 48.679,12.037C48.795,11.41 49.288,10.974 49.887,10.806C51.328,10.401 52.556,11.484 53.226,12.649C53.292,12.764 53.426,12.781 53.537,12.731C55.082,12.036 56.06,10.325 55.874,8.641L55.487,8.802C56.401,9.645 57.967,10.617 59.186,9.771C59.979,9.221 60.45,7.899 59.592,7.19C59.371,7.007 59.059,7.302 59.271,7.511C60.339,8.563 62.045,8.785 63.348,8.043C63.602,7.898 63.373,7.506 63.118,7.651C61.993,8.292 60.515,8.099 59.592,7.19L59.271,7.511C59.935,8.06 59.474,9.092 58.837,9.455C57.81,10.04 56.54,9.156 55.808,8.481C55.678,8.361 55.397,8.432 55.42,8.641C55.59,10.184 54.724,11.702 53.308,12.339L53.619,12.42C52.796,10.99 51.172,9.751 49.464,10.475C48.77,10.769 48.286,11.372 48.21,12.128C48.141,12.814 48.422,13.509 49.02,13.875L49.134,13.452C46.643,13.757 44.144,14.521 41.87,15.577L42.099,15.969L42.571,15.671C42.78,15.539 42.65,15.171 42.396,15.256C38.54,16.556 34.975,18.666 31.979,21.42C30.427,22.848 29.071,24.451 27.83,26.152C26.506,27.967 25.29,29.861 23.892,31.622C22.267,33.67 20.343,35.404 18.303,37.028L18.524,36.97C15.56,36.367 12.602,35.51 9.881,34.172C8.609,33.547 7.384,32.805 6.288,31.904C5.242,31.043 4.102,29.987 3.738,28.633C3.556,27.953 3.625,27.266 3.997,26.662C4.349,26.09 4.932,25.694 5.618,25.747C5.879,25.768 5.919,25.37 5.679,25.301C4.958,25.095 4.398,24.424 3.936,23.87C3.418,23.25 2.922,22.593 2.463,21.928C1.893,21.103 1.459,20.187 1.202,19.216C0.949,18.258 0.805,17.161 1.14,16.205C1.471,15.261 2.471,14.474 3.495,14.863C3.741,14.956 3.884,14.577 3.67,14.448C2.967,14.023 2.328,13.484 1.841,12.819C1.601,12.492 1.395,12.135 1.243,11.759C1.174,11.584 1.082,11.381 1.07,11.193C1.054,10.951 1.139,10.673 1.18,10.434C1.264,9.947 1.357,9.461 1.465,8.978C1.52,8.731 1.578,8.485 1.641,8.24C1.706,7.982 1.789,7.843 1.983,7.66C2.618,7.062 3.496,6.767 4.353,6.693C5.481,6.596 6.596,6.846 7.683,7.113C7.909,7.169 8.056,6.901 7.904,6.734C7.312,6.079 7.065,5.258 7.302,4.396C7.529,3.57 8.089,2.861 8.714,2.294C10.184,0.958 12.199,0.478 14.144,0.455C18.684,0.402 22.791,2.7 27.229,3.297C31.893,3.924 36.493,2.592 41.091,2.029C44.799,1.575 48.589,1.743 52.242,2.531C55.843,3.308 59.39,4.696 62.327,6.956C62.681,7.228 63.024,7.514 63.357,7.811L63.403,7.455C63.31,7.524 63.217,7.589 63.118,7.651C62.871,7.806 63.099,8.199 63.348,8.043Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M50.575,27.469C53.118,27.683 55.925,28.056 58.333,28.922C59.003,29.163 59.74,29.463 60.04,30.109C60.276,30.618 60.176,31.212 60.065,31.762C59.253,35.775 58.323,39.708 57.497,43.717C56.641,47.871 55.6,51.951 54.078,55.914C53.896,56.389 53.696,56.876 53.325,57.223C52.917,57.605 52.353,57.767 51.808,57.891C48.383,58.675 44.82,58.496 41.314,58.264C35.998,57.911 30.685,57.447 25.408,56.697C22.732,56.317 20.058,55.876 17.413,55.313C15.958,55.002 13.01,54.59 12.384,53.056C12.054,52.248 12.32,51.332 12.579,50.498C14.749,43.522 16.354,36.37 17.372,29.136C17.496,28.256 17.615,27.36 17.975,26.547C19.12,23.964 21.822,24.719 24.12,24.857C27.101,25.036 30.078,25.274 33.05,25.571C37.366,26.002 41.716,26.937 46.03,27.188C47.548,27.277 49.067,27.343 50.575,27.469Z"
android:fillColor="#662D91"/>
<path
android:pathData="M19.285,27.949C20.125,28.802 20.543,29.605 21.166,30.579C21.978,31.848 23.153,32.975 24.135,34.116C26.193,36.51 28.283,38.879 30.454,41.172C31.452,42.226 32.527,43.302 33.912,43.738C35.804,44.335 37.839,43.616 39.66,42.831C46.359,39.945 52.976,36.033 58.492,31.278"
android:fillColor="#662D91"/>
<path
android:pathData="M41.984,15.773C35.499,18.361 29.736,22.956 26.252,29.006C22.768,35.057 21.708,42.576 23.912,49.201C24.185,50.021 24.507,50.835 24.615,51.693C24.723,52.55 24.59,53.482 24.038,54.147C23.732,54.517 23.303,54.633 23.025,55.001C22.846,55.24 22.66,55.492 22.614,55.787C22.568,56.082 22.713,56.43 23.002,56.506C23.374,56.603 23.726,56.223 24.109,56.26C23.952,56.571 23.823,56.915 23.862,57.261C23.902,57.607 24.155,57.95 24.502,57.988C24.9,58.031 25.223,57.689 25.475,57.378C25.288,57.762 25.118,58.27 25.419,58.572C25.613,58.768 25.94,58.776 26.189,58.659C26.439,58.542 26.625,58.325 26.789,58.104C26.781,58.456 26.62,58.882 27.03,59.101C27.313,59.252 27.676,59.169 27.932,58.975C28.187,58.781 28.355,58.496 28.502,58.21C28.688,57.848 28.85,57.473 28.988,57.09C29.045,57.461 29.273,57.802 29.594,57.996C29.819,58.132 30.117,58.193 30.343,58.058C30.633,57.886 30.68,57.493 30.695,57.156C30.749,55.946 30.677,54.669 30.83,53.481C31.003,52.131 31.142,50.778 31.232,49.42C31.387,47.06 31.416,44.687 31.294,42.325C31.217,40.834 31.058,38.439 31.911,37.165C32.137,36.828 32.441,36.552 32.744,36.284C37.543,32.041 41.675,29.619 47.19,26.362"
android:fillColor="#FFDE17"/>
<path
android:pathData="M41.925,15.554C38.861,16.781 35.976,18.43 33.389,20.481C30.821,22.515 28.562,24.948 26.783,27.703C24.881,30.648 23.563,33.968 22.944,37.42C22.325,40.875 22.396,44.461 23.281,47.864C23.513,48.756 23.835,49.614 24.108,50.493C24.375,51.354 24.557,52.276 24.299,53.163C24.18,53.571 23.966,53.967 23.624,54.229C23.3,54.477 22.993,54.661 22.748,54.998C22.52,55.311 22.328,55.674 22.397,56.073C22.456,56.413 22.707,56.71 23.063,56.744C23.443,56.78 23.74,56.471 24.11,56.487L23.914,56.145C23.62,56.742 23.435,57.544 24.039,58.025C24.629,58.495 25.251,58.009 25.638,57.539L25.281,57.264C25.044,57.759 24.822,58.513 25.422,58.855C26.042,59.208 26.634,58.687 26.987,58.218L26.564,58.104C26.55,58.431 26.456,58.778 26.658,59.07C26.887,59.401 27.349,59.469 27.709,59.346C28.105,59.212 28.381,58.889 28.584,58.537C28.838,58.099 29.036,57.625 29.209,57.15H28.771C28.876,57.735 29.352,58.298 29.97,58.356C30.652,58.419 30.887,57.777 30.921,57.216C30.966,56.458 30.943,55.697 30.961,54.939C30.979,54.165 31.073,53.405 31.163,52.637C31.535,49.458 31.679,46.25 31.555,43.051C31.509,41.859 31.402,40.665 31.496,39.473C31.54,38.914 31.628,38.348 31.83,37.823C32.063,37.214 32.516,36.788 32.996,36.365C35.051,34.555 37.224,32.888 39.497,31.361C41.73,29.861 44.044,28.486 46.359,27.117C46.674,26.931 46.99,26.744 47.306,26.558C47.558,26.409 47.329,26.016 47.077,26.166C44.774,27.525 42.466,28.878 40.224,30.337C38.044,31.756 35.939,33.287 33.943,34.955C33.398,35.411 32.851,35.868 32.331,36.352C31.901,36.753 31.574,37.201 31.372,37.754C30.986,38.812 30.981,40.003 31.014,41.115C31.053,42.459 31.14,43.8 31.144,45.146C31.148,46.713 31.092,48.281 30.977,49.844C30.921,50.607 30.85,51.369 30.766,52.13C30.683,52.888 30.564,53.644 30.526,54.407C30.488,55.16 30.502,55.915 30.485,56.668C30.478,56.974 30.499,57.313 30.404,57.608C30.294,57.955 29.956,57.959 29.682,57.782C29.418,57.611 29.264,57.334 29.209,57.029C29.165,56.789 28.84,56.84 28.771,57.029C28.638,57.394 28.485,57.75 28.307,58.096C28.172,58.358 28.018,58.646 27.766,58.816C27.571,58.948 27.177,59.052 27.022,58.799C26.91,58.614 27.01,58.306 27.018,58.104C27.028,57.856 26.718,57.825 26.595,57.989C26.397,58.251 26.022,58.668 25.651,58.463C25.313,58.276 25.554,57.743 25.673,57.493C25.776,57.278 25.492,57.004 25.316,57.218C25.096,57.486 24.692,57.974 24.316,57.667C23.914,57.339 24.118,56.757 24.306,56.374C24.383,56.218 24.29,56.04 24.11,56.033C23.922,56.025 23.751,56.077 23.579,56.149C23.431,56.211 23.231,56.333 23.064,56.287C22.648,56.172 22.897,55.588 23.041,55.37C23.149,55.206 23.267,55.049 23.42,54.925C23.574,54.8 23.749,54.702 23.906,54.581C24.219,54.341 24.445,54.016 24.601,53.656C25.333,51.968 24.446,50.203 23.956,48.584C22.961,45.301 22.752,41.797 23.242,38.406C23.733,35.009 24.899,31.717 26.656,28.769C28.292,26.023 30.412,23.583 32.843,21.514C35.274,19.445 38.021,17.748 40.94,16.457C41.306,16.295 41.675,16.141 42.046,15.992C42.314,15.885 42.197,15.445 41.925,15.554Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M43.187,41.564C45.582,44.855 47.767,48.297 49.722,51.867C50.267,52.862 50.794,53.868 51.303,54.882C51.435,55.143 51.826,54.914 51.695,54.653C49.869,51.016 47.811,47.496 45.534,44.123C44.9,43.182 44.247,42.253 43.579,41.335C43.409,41.101 43.015,41.327 43.187,41.564Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M14.989,51.589C16.963,49.584 19.077,47.705 21.259,45.93C21.83,45.465 22.407,45.009 22.996,44.567C23.227,44.394 23.001,43.999 22.767,44.175C20.501,45.876 18.349,47.741 16.289,49.685C15.739,50.203 15.198,50.73 14.667,51.268C14.462,51.477 14.783,51.798 14.989,51.589Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M34.414,37.459C35.472,37.016 36.846,37.671 37.283,38.696C37.543,39.306 37.582,40.06 37.188,40.593C37.067,40.757 36.911,40.893 36.741,41.005C36.217,41.35 35.549,41.467 34.939,41.321C33.204,40.906 32.572,38.229 34.414,37.459Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M34.475,37.677C35.243,37.368 36.132,37.645 36.696,38.225C37.283,38.829 37.523,39.979 36.863,40.619C36.225,41.238 35.139,41.335 34.406,40.836C33.913,40.501 33.585,39.906 33.536,39.315C33.474,38.571 33.843,37.949 34.529,37.654C34.643,37.606 34.666,37.441 34.611,37.344C34.544,37.226 34.412,37.214 34.3,37.262C33.551,37.584 33.086,38.293 33.074,39.107C33.064,39.864 33.422,40.636 34.015,41.108C34.841,41.766 36.069,41.765 36.925,41.153C37.404,40.81 37.678,40.315 37.707,39.725C37.732,39.21 37.579,38.653 37.284,38.229C36.66,37.333 35.401,36.818 34.354,37.239C34.24,37.285 34.162,37.39 34.196,37.519C34.224,37.627 34.361,37.723 34.475,37.677Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M70.994,81.258C71.335,80.527 71.204,79.744 70.702,79.51C70.2,79.276 69.516,79.68 69.176,80.412C68.835,81.143 68.966,81.926 69.468,82.16C69.97,82.394 70.653,81.99 70.994,81.258Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M70.801,81.145C70.623,81.518 70.302,81.932 69.865,81.995C69.487,82.05 69.256,81.719 69.222,81.364C69.174,80.864 69.392,80.336 69.748,79.988C69.99,79.752 70.395,79.54 70.697,79.77C71.098,80.075 70.977,80.757 70.801,81.145C70.75,81.257 70.769,81.389 70.882,81.456C70.979,81.513 71.142,81.487 71.193,81.374C71.45,80.807 71.55,80.047 71.109,79.538C70.732,79.103 70.101,79.16 69.666,79.469C69.122,79.856 68.777,80.526 68.762,81.192C68.749,81.762 69.044,82.37 69.663,82.446C70.343,82.53 70.924,81.937 71.193,81.374C71.246,81.264 71.223,81.129 71.111,81.064C71.012,81.006 70.854,81.034 70.801,81.145Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M65.263,81.258C65.604,80.527 65.473,79.744 64.971,79.51C64.469,79.276 63.786,79.68 63.445,80.412C63.104,81.143 63.235,81.926 63.737,82.16C64.239,82.394 64.923,81.99 65.263,81.258Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M65.07,81.145C64.892,81.518 64.571,81.932 64.134,81.995C63.757,82.05 63.526,81.719 63.491,81.364C63.443,80.864 63.662,80.336 64.018,79.988C64.259,79.752 64.664,79.54 64.967,79.77C65.368,80.075 65.246,80.757 65.07,81.145C65.02,81.257 65.038,81.389 65.152,81.456C65.249,81.513 65.411,81.487 65.462,81.374C65.72,80.807 65.82,80.047 65.379,79.538C65.002,79.103 64.371,79.16 63.935,79.469C63.391,79.856 63.046,80.526 63.032,81.192C63.019,81.762 63.314,82.37 63.932,82.446C64.613,82.53 65.193,81.937 65.462,81.374C65.515,81.264 65.493,81.129 65.381,81.064C65.282,81.006 65.123,81.034 65.07,81.145Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M32.443,81.258C32.784,80.527 32.653,79.744 32.151,79.51C31.649,79.276 30.966,79.68 30.625,80.412C30.284,81.143 30.415,81.926 30.917,82.16C31.419,82.394 32.102,81.99 32.443,81.258Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M32.246,81.145C32.068,81.518 31.747,81.932 31.31,81.995C30.933,82.05 30.702,81.719 30.667,81.364C30.619,80.864 30.837,80.336 31.193,79.988C31.435,79.752 31.84,79.54 32.143,79.77C32.544,80.075 32.422,80.757 32.246,81.145C32.195,81.257 32.214,81.389 32.327,81.456C32.425,81.513 32.587,81.487 32.638,81.374C32.896,80.807 32.996,80.047 32.555,79.538C32.178,79.103 31.546,79.16 31.111,79.469C30.567,79.856 30.222,80.526 30.207,81.192C30.195,81.762 30.49,82.37 31.108,82.446C31.789,82.53 32.369,81.937 32.638,81.374C32.691,81.264 32.669,81.129 32.557,81.064C32.458,81.006 32.299,81.034 32.246,81.145Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M61.562,71.494C62.833,72.622 64.374,73.421 66.032,73.798C66.316,73.862 66.438,73.425 66.153,73.36C64.572,73 63.096,72.25 61.883,71.173C61.665,70.98 61.342,71.3 61.562,71.494Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M63.569,69.748C63.624,69.715 63.681,69.685 63.741,69.66L63.687,69.683C63.79,69.64 63.898,69.61 64.01,69.595L63.949,69.603C64.031,69.592 64.112,69.589 64.194,69.593C64.313,69.599 64.426,69.484 64.421,69.366C64.415,69.237 64.321,69.145 64.194,69.139C63.897,69.123 63.593,69.202 63.339,69.356C63.238,69.418 63.191,69.563 63.258,69.667C63.324,69.769 63.46,69.814 63.569,69.748Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M64.251,70.729C64.261,70.714 64.271,70.7 64.282,70.686L64.247,70.731C64.295,70.67 64.351,70.615 64.412,70.566L64.366,70.602C64.432,70.552 64.502,70.51 64.577,70.478L64.523,70.501C64.599,70.469 64.677,70.447 64.759,70.435L64.698,70.443C64.716,70.441 64.734,70.439 64.751,70.437C64.813,70.432 64.867,70.415 64.912,70.371C64.951,70.331 64.981,70.267 64.979,70.21C64.973,70.096 64.878,69.972 64.751,69.983C64.572,69.998 64.4,70.047 64.243,70.138C64.088,70.228 63.96,70.353 63.859,70.499C63.827,70.546 63.821,70.622 63.836,70.674C63.85,70.727 63.891,70.784 63.94,70.81C64.056,70.871 64.179,70.833 64.251,70.729Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M34.252,65.89C34.599,66.33 35.049,66.683 35.474,67.045C35.921,67.425 36.372,67.799 36.827,68.168C37.737,68.903 38.665,69.616 39.61,70.306C40.153,70.703 40.702,71.091 41.257,71.473C41.498,71.639 41.726,71.245 41.486,71.08C39.579,69.769 37.737,68.365 35.969,66.871C35.487,66.464 34.966,66.067 34.573,65.569C34.392,65.34 34.073,65.663 34.252,65.89Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M53.766,66.853C56.181,66.792 58.602,66.65 60.964,66.109C61.652,65.951 62.331,65.761 63.002,65.544C63.279,65.454 63.161,65.016 62.882,65.106C60.601,65.845 58.246,66.192 55.857,66.321C55.161,66.358 54.463,66.381 53.766,66.399C53.474,66.406 53.473,66.861 53.766,66.853Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M38.766,68.111C40.521,66.205 42.014,64.059 43.18,61.744C43.511,61.086 43.815,60.414 44.095,59.732C44.141,59.617 44.044,59.483 43.936,59.452C43.806,59.415 43.703,59.498 43.657,59.611C42.696,61.951 41.407,64.165 39.842,66.152C39.398,66.716 38.931,67.262 38.445,67.79C38.247,68.005 38.568,68.326 38.766,68.111Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M55.948,48.692C57.197,52.895 58.03,57.22 58.422,61.587C58.532,62.816 58.607,64.047 58.649,65.279C58.659,65.571 59.113,65.572 59.103,65.279C59.028,63.078 58.845,60.882 58.553,58.699C58.259,56.507 57.859,54.329 57.349,52.177C57.062,50.966 56.74,49.764 56.386,48.571C56.303,48.292 55.864,48.411 55.948,48.692Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M36.618,74.05C36.791,76.03 37.469,77.947 38.597,79.585C38.762,79.824 39.155,79.597 38.989,79.356C37.908,77.785 37.238,75.95 37.072,74.05C37.047,73.761 36.593,73.758 36.618,74.05Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M38.671,75.069C38.695,75.063 38.722,75.062 38.745,75.054C38.734,75.058 38.697,75.059 38.729,75.057C38.742,75.056 38.754,75.054 38.766,75.054C38.811,75.051 38.856,75.051 38.901,75.054C38.904,75.055 38.937,75.061 38.938,75.058C38.935,75.063 38.881,75.049 38.93,75.057C38.952,75.061 38.974,75.065 38.996,75.071C39.043,75.082 39.087,75.098 39.132,75.113C39.161,75.123 39.092,75.095 39.12,75.107C39.131,75.113 39.142,75.118 39.154,75.123C39.174,75.133 39.194,75.144 39.214,75.155C39.233,75.166 39.252,75.177 39.271,75.19C39.282,75.197 39.292,75.204 39.302,75.211C39.329,75.23 39.312,75.224 39.298,75.207C39.327,75.24 39.367,75.266 39.397,75.298C39.413,75.314 39.429,75.341 39.447,75.354C39.438,75.348 39.421,75.319 39.438,75.344C39.447,75.356 39.456,75.369 39.464,75.381C39.53,75.48 39.668,75.532 39.775,75.463C39.873,75.399 39.927,75.258 39.856,75.152C39.574,74.728 39.048,74.515 38.55,74.631C38.435,74.658 38.355,74.797 38.392,74.91C38.431,75.031 38.547,75.098 38.671,75.069Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M39,76.705C39.029,76.698 39.058,76.692 39.089,76.688L39.028,76.696C39.092,76.688 39.155,76.688 39.219,76.696L39.159,76.688C39.222,76.697 39.284,76.714 39.343,76.739L39.289,76.716C39.345,76.74 39.397,76.77 39.445,76.807L39.399,76.772C39.41,76.78 39.42,76.788 39.43,76.797C39.476,76.837 39.528,76.864 39.591,76.864C39.646,76.864 39.713,76.839 39.751,76.797C39.83,76.712 39.847,76.559 39.751,76.476C39.512,76.269 39.187,76.186 38.879,76.267C38.764,76.298 38.683,76.431 38.72,76.547C38.758,76.665 38.877,76.738 39,76.705Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M64.165,42.437C64.443,41.339 65.259,40.502 66.004,39.693C66.78,38.851 67.569,38.013 68.468,37.3C68.971,36.901 69.512,36.552 70.088,36.268C70.35,36.138 70.12,35.746 69.858,35.875C68.79,36.403 67.857,37.162 67.008,37.99C66.586,38.402 66.182,38.831 65.782,39.264C65.384,39.695 64.981,40.125 64.622,40.59C64.222,41.108 63.889,41.677 63.727,42.316C63.655,42.599 64.093,42.72 64.165,42.437Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M28.418,26.932C30.813,27.91 32.913,29.609 34.39,31.731C34.814,32.34 35.186,32.982 35.505,33.652C35.63,33.915 36.022,33.685 35.897,33.422C34.741,30.995 32.862,28.928 30.573,27.521C29.925,27.122 29.243,26.782 28.538,26.494C28.424,26.448 28.29,26.545 28.259,26.653C28.222,26.783 28.305,26.886 28.418,26.932Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M78.983,18.773C78.797,19.225 78.61,19.677 78.424,20.129C78.267,20.508 78.015,20.947 78.187,21.362C78.581,22.313 79.765,21.285 80.146,20.844L79.767,20.623C79.694,21.066 79.608,21.978 80.187,22.136C80.74,22.287 81.201,21.639 81.405,21.222L80.99,21.047C80.825,21.458 80.741,22.054 81.246,22.264C81.773,22.483 82.197,22.037 82.452,21.635L82.029,21.52C81.984,21.876 82.265,22.206 82.601,22.293C82.985,22.391 83.367,22.211 83.659,21.972C84.22,21.512 84.468,20.786 84.685,20.12C84.776,19.841 84.338,19.722 84.247,19.999C84.089,20.484 83.924,21 83.592,21.399C83.428,21.596 83.209,21.792 82.953,21.85C82.724,21.902 82.449,21.792 82.483,21.52C82.513,21.281 82.169,21.233 82.06,21.405C81.94,21.593 81.701,21.969 81.422,21.847C81.183,21.742 81.363,21.33 81.427,21.168C81.523,20.93 81.125,20.762 81.012,20.993C80.933,21.155 80.839,21.31 80.719,21.446C80.633,21.544 80.484,21.713 80.338,21.701C80.205,21.69 80.198,21.463 80.188,21.364C80.165,21.158 80.171,20.948 80.205,20.744C80.238,20.543 79.989,20.333 79.825,20.523C79.62,20.76 79.386,20.968 79.118,21.132C79.015,21.194 78.806,21.354 78.68,21.287C78.564,21.225 78.575,21.044 78.597,20.941C78.671,20.6 78.856,20.263 78.989,19.942C79.133,19.592 79.277,19.243 79.421,18.894C79.468,18.78 79.37,18.645 79.263,18.615C79.133,18.577 79.03,18.66 78.983,18.773Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M78.029,18.503C78.053,18.519 78.077,18.537 78.102,18.553C78.123,18.567 78.077,18.533 78.11,18.56C78.12,18.568 78.13,18.576 78.14,18.585C78.187,18.625 78.231,18.669 78.273,18.715C78.293,18.737 78.311,18.76 78.33,18.783C78.31,18.757 78.325,18.777 78.336,18.791C78.343,18.802 78.351,18.813 78.358,18.824C78.393,18.875 78.425,18.928 78.454,18.984C78.467,19.01 78.479,19.037 78.492,19.064C78.48,19.031 78.507,19.095 78.492,19.064C78.497,19.079 78.504,19.094 78.509,19.11C78.529,19.165 78.546,19.222 78.559,19.279C78.566,19.311 78.572,19.343 78.578,19.375C78.582,19.399 78.58,19.394 78.578,19.373C78.579,19.389 78.581,19.406 78.582,19.422C78.588,19.484 78.588,19.546 78.585,19.608C78.58,19.727 78.694,19.841 78.813,19.835C78.94,19.83 79.034,19.736 79.04,19.608C79.067,19.013 78.755,18.433 78.258,18.111C78.158,18.046 78.003,18.087 77.947,18.192C77.887,18.306 77.922,18.434 78.029,18.503Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M77.084,20.202C77.502,20.496 78.044,20.766 78.56,20.553C78.669,20.508 78.759,20.4 78.718,20.274C78.684,20.168 78.556,20.066 78.439,20.115C78.317,20.166 78.257,20.174 78.147,20.172C78.117,20.172 78.087,20.17 78.057,20.167C78.096,20.171 78.034,20.163 78.027,20.162C77.971,20.151 77.916,20.137 77.862,20.119C77.837,20.11 77.812,20.101 77.787,20.091C77.823,20.105 77.745,20.072 77.738,20.069C77.691,20.046 77.644,20.021 77.598,19.995C77.5,19.938 77.406,19.875 77.313,19.809C77.215,19.741 77.056,19.789 77.002,19.891C76.94,20.007 76.979,20.128 77.084,20.202Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M81.208,22.208C81.221,22.217 81.234,22.225 81.246,22.234C81.25,22.237 81.283,22.259 81.26,22.243C81.234,22.225 81.275,22.255 81.28,22.259C81.289,22.267 81.298,22.275 81.307,22.283C81.35,22.321 81.39,22.363 81.427,22.407C81.434,22.415 81.459,22.451 81.431,22.411C81.438,22.421 81.445,22.431 81.452,22.441C81.468,22.463 81.483,22.486 81.497,22.509C81.528,22.559 81.553,22.61 81.577,22.663C81.569,22.645 81.567,22.635 81.575,22.659C81.581,22.673 81.586,22.687 81.591,22.702C81.6,22.727 81.608,22.753 81.616,22.78C81.623,22.806 81.629,22.833 81.635,22.86C81.639,22.879 81.649,22.951 81.643,22.898C81.649,22.955 81.653,23.013 81.652,23.07C81.651,23.098 81.649,23.125 81.647,23.152C81.646,23.179 81.646,23.164 81.649,23.146C81.646,23.164 81.643,23.182 81.64,23.2C81.618,23.316 81.672,23.45 81.799,23.479C81.91,23.504 82.055,23.445 82.078,23.32C82.186,22.74 81.935,22.139 81.438,21.816C81.338,21.751 81.182,21.793 81.127,21.898C81.067,22.011 81.102,22.139 81.208,22.208Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M7.072,48.525C7.841,48.659 8.61,48.794 9.379,48.929C9.5,48.95 9.624,48.897 9.659,48.77C9.689,48.661 9.622,48.512 9.5,48.491C8.731,48.356 7.962,48.221 7.193,48.086C7.072,48.065 6.948,48.119 6.913,48.245C6.883,48.355 6.951,48.503 7.072,48.525Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M7.594,55.682C8.062,55.213 8.53,54.745 8.999,54.277C9.083,54.193 9.089,54.039 8.999,53.956C8.908,53.872 8.767,53.866 8.677,53.956C8.209,54.424 7.741,54.892 7.272,55.36C7.188,55.444 7.182,55.599 7.272,55.682C7.363,55.765 7.504,55.771 7.594,55.682Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M12.483,58.332C12.474,58.23 12.471,58.127 12.475,58.024C12.477,57.973 12.48,57.921 12.485,57.87C12.487,57.848 12.49,57.826 12.492,57.804C12.496,57.777 12.496,57.775 12.493,57.799C12.495,57.788 12.496,57.778 12.498,57.767C12.53,57.567 12.585,57.372 12.662,57.185C12.707,57.075 12.613,56.93 12.503,56.905C12.371,56.875 12.272,56.946 12.224,57.064C12.061,57.463 11.994,57.903 12.028,58.332C12.038,58.45 12.126,58.565 12.255,58.559C12.37,58.554 12.493,58.459 12.483,58.332Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M10.259,44.792C10.455,45.084 10.692,45.35 10.966,45.572C11.014,45.611 11.062,45.638 11.127,45.638C11.182,45.638 11.249,45.614 11.287,45.572C11.363,45.489 11.386,45.331 11.287,45.251C11.088,45.089 10.908,44.906 10.75,44.703L10.786,44.749C10.739,44.688 10.694,44.626 10.651,44.562C10.585,44.464 10.448,44.411 10.34,44.481C10.242,44.544 10.188,44.686 10.259,44.792Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M6.423,82.958C16.061,82.958 25.7,82.958 35.339,82.958C44.928,82.958 54.518,82.958 64.107,82.958C69.517,82.958 74.926,82.958 80.336,82.958C80.628,82.958 80.629,82.504 80.336,82.504C70.697,82.504 61.058,82.504 51.42,82.504C41.83,82.504 32.241,82.504 22.651,82.504H6.423C6.13,82.504 6.13,82.958 6.423,82.958Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M13.059,82.548C12.719,82.535 12.414,82.178 12.503,81.837C12.587,81.519 12.956,81.342 13.259,81.435C13.471,81.499 13.651,81.207 13.48,81.055C12.855,80.501 13.127,79.543 13.801,79.154C14.516,78.742 15.484,78.889 16.164,79.296C16.577,79.544 16.904,79.898 17.109,80.334L17.501,80.105C17.099,79.318 17.483,78.341 18.142,77.823C18.918,77.213 19.99,77.388 20.711,78.001C21.145,78.369 21.452,78.859 21.573,79.417L21.953,79.196C21.757,78.971 21.819,78.631 21.974,78.402C22.17,78.114 22.513,78.032 22.84,78.12C23.761,78.37 23.91,79.447 23.758,80.247C23.703,80.535 24.097,80.644 24.196,80.368C24.325,80.007 24.758,79.902 25.102,79.931C25.559,79.969 25.923,80.282 26.231,80.597C26.594,80.967 26.912,81.376 27.337,81.68C27.777,81.995 28.32,82.179 28.856,82.031C29.138,81.953 29.018,81.515 28.736,81.593C28.163,81.751 27.612,81.377 27.223,80.992C26.836,80.609 26.507,80.171 26.064,79.847C25.678,79.564 25.223,79.423 24.745,79.491C24.296,79.555 23.913,79.812 23.758,80.247L24.196,80.368C24.311,79.76 24.308,79.115 24.02,78.553C23.776,78.074 23.296,77.714 22.76,77.644C22.263,77.579 21.785,77.8 21.539,78.242C21.311,78.652 21.316,79.156 21.631,79.517C21.79,79.699 22.056,79.502 22.011,79.296C21.762,78.149 20.766,77.172 19.593,77.008C18.458,76.85 17.437,77.554 17.034,78.603C16.818,79.166 16.833,79.795 17.109,80.334C17.243,80.596 17.624,80.366 17.501,80.105C17.061,79.169 16.091,78.575 15.079,78.474C14.079,78.375 13.012,78.83 12.725,79.861C12.571,80.415 12.727,80.993 13.159,81.376L13.38,80.997C12.83,80.828 12.175,81.185 12.055,81.759C11.926,82.381 12.439,82.979 13.059,83.002C13.351,83.012 13.351,82.558 13.059,82.548Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M61.938,81.108C61.146,80.482 60.194,80.016 59.191,79.858C58.745,79.789 58.213,79.804 57.914,80.196C57.683,80.498 57.641,80.988 57.965,81.245L58.24,80.888C57.826,80.618 57.357,80.458 56.866,80.412C56.451,80.373 55.979,80.418 55.626,80.661C55.295,80.889 55.106,81.272 55.246,81.668C55.37,82.018 55.711,82.289 56.092,82.175C56.372,82.091 56.253,81.653 55.972,81.737C55.779,81.795 55.649,81.55 55.651,81.385C55.654,81.133 55.933,80.98 56.145,80.917C56.768,80.732 57.482,80.936 58.011,81.28C58.223,81.419 58.489,81.086 58.286,80.924C58.088,80.767 58.208,80.467 58.403,80.361C58.734,80.182 59.18,80.305 59.52,80.393C60.281,80.589 61,80.942 61.617,81.429C61.844,81.608 62.167,81.289 61.938,81.108Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M58.498,14.348C59.132,15.793 60.837,16.5 62.31,15.936C62.58,15.832 62.463,15.393 62.189,15.498C61.532,15.749 60.782,15.749 60.143,15.437C59.577,15.161 59.142,14.693 58.89,14.119C58.773,13.852 58.382,14.083 58.498,14.348Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M65.635,16.013C65.955,16.555 66.61,16.842 67.224,16.68C67.524,16.601 67.798,16.422 67.989,16.178C68.205,15.9 68.295,15.56 68.358,15.22C68.38,15.1 68.325,14.975 68.199,14.941C68.089,14.91 67.942,14.978 67.92,15.099C67.871,15.366 67.815,15.644 67.656,15.869C67.532,16.044 67.341,16.173 67.137,16.233C66.71,16.359 66.252,16.164 66.027,15.784C65.878,15.533 65.485,15.761 65.635,16.013Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M64.938,12.857C65.059,14.853 65.016,16.855 64.81,18.843C64.78,19.134 65.234,19.132 65.264,18.843C65.47,16.855 65.513,14.853 65.392,12.857C65.375,12.567 64.92,12.565 64.938,12.857Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M62.756,19.834C62.379,19.308 61.989,18.728 61.446,18.358C61.204,18.193 60.896,18.102 60.611,18.201C60.339,18.295 60.142,18.52 60.006,18.765C59.692,19.332 59.562,20.035 59.521,20.675C59.48,21.313 59.514,22.044 59.96,22.545C60.396,23.034 61.221,23.102 61.596,22.503C61.751,22.254 61.358,22.026 61.203,22.274C60.964,22.657 60.451,22.46 60.235,22.166C59.931,21.753 59.944,21.163 59.975,20.675C60.008,20.159 60.117,19.624 60.323,19.147C60.398,18.974 60.5,18.784 60.662,18.677C60.857,18.55 61.069,18.642 61.239,18.765C61.7,19.097 62.038,19.608 62.364,20.063C62.533,20.298 62.927,20.072 62.756,19.834Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M59.947,19.4C60.334,20.207 60.934,20.911 61.668,21.422C61.724,21.461 61.786,21.506 61.797,21.573C61.802,21.606 61.794,21.638 61.785,21.67C61.719,21.91 61.589,22.138 61.39,22.288C61.191,22.438 60.92,22.501 60.685,22.42C60.325,22.296 60.146,21.897 60.047,21.53C59.919,21.059 59.853,20.572 59.852,20.085C59.851,20.006 59.908,19.893 59.974,19.936"
android:fillColor="#3B1954"/>
<path
android:pathData="M59.751,19.515C60.129,20.292 60.689,20.967 61.376,21.489C61.415,21.518 61.454,21.547 61.494,21.576C61.53,21.602 61.569,21.654 61.567,21.61C61.572,21.689 61.492,21.813 61.453,21.878C61.352,22.049 61.192,22.189 60.991,22.222C60.604,22.286 60.401,21.903 60.302,21.593C60.221,21.339 60.166,21.073 60.129,20.809C60.111,20.681 60.098,20.552 60.09,20.423C60.085,20.348 60.082,20.273 60.08,20.198C60.08,20.177 60.087,20.132 60.079,20.114C60.054,20.058 60.139,20.114 60.007,20.146H59.886L59.914,20.156C60.191,20.25 60.31,19.812 60.035,19.718C59.902,19.672 59.764,19.734 59.692,19.851C59.616,19.975 59.623,20.114 59.628,20.254C59.638,20.574 59.676,20.893 59.738,21.207C59.834,21.695 59.987,22.302 60.457,22.565C60.972,22.855 61.583,22.569 61.857,22.087C61.995,21.845 62.125,21.515 61.879,21.299C61.674,21.119 61.442,20.974 61.242,20.785C60.785,20.357 60.417,19.849 60.143,19.286C60.015,19.023 59.624,19.253 59.751,19.515Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M59.268,12.047C60.535,11.447 61.944,11.198 63.341,11.308C63.632,11.331 63.631,10.877 63.341,10.854C61.862,10.737 60.377,11.021 59.039,11.655C58.775,11.78 59.005,12.172 59.268,12.047Z"
android:fillColor="#3B1954"/>
<path
android:pathData="M65.2,12.962C65.588,12.943 65.976,12.923 66.364,12.904C66.482,12.898 66.597,12.804 66.591,12.677C66.586,12.559 66.491,12.443 66.364,12.45C65.976,12.469 65.588,12.488 65.2,12.508C65.081,12.514 64.967,12.608 64.973,12.735C64.978,12.853 65.073,12.969 65.2,12.962Z"
android:fillColor="#3B1954"/>
</vector>

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M382,720L154,492L211,435L382,606L749,239L806,296L382,720Z"/>
</vector>
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View File

@ -0,0 +1,38 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="101dp"
android:height="100dp"
android:viewportWidth="101"
android:viewportHeight="100">
<path
android:pathData="M22.51,49.31C20.1,50.42 17.47,52.54 15.18,53.97C13.11,55.25 9.42,57.92 8.52,60.29C10.11,56.11 11.69,51.94 13.27,47.76C13.42,47.35 13.58,46.91 13.48,46.48C13.31,45.76 12.51,45.42 11.85,45.09C6.15,42.28 5.32,32.64 7.18,27.31C9.08,21.89 13.53,17.64 18.63,15C23.73,12.36 29.46,11.17 35.15,10.42C42.77,9.42 50.91,9.23 57.73,12.78C64.55,16.34 69.39,24.69 66.67,31.89C64.85,36.72 60.23,39.9 55.6,42.19C46.67,46.61 36.7,48.89 26.74,48.78C25.31,48.76 23.82,48.71 22.51,49.31Z"
android:fillColor="#332E36"/>
<path
android:pathData="M22.12,48.64C20.51,49.4 19.03,50.42 17.56,51.44C16.31,52.31 15.01,53.12 13.75,53.98C11.47,55.52 8.83,57.44 7.78,60.08L9.27,60.49C10.47,57.33 11.67,54.16 12.87,50.99C13.14,50.27 13.41,49.55 13.69,48.83C13.96,48.11 14.35,47.35 14.27,46.56C14.13,45.24 12.89,44.81 11.89,44.24C8.41,42.29 7.24,37.76 7.08,34.05C7,32.11 7.16,30.14 7.69,28.26C8.36,25.92 9.62,23.73 11.18,21.86C14.75,17.56 19.76,14.86 25.05,13.26C27.94,12.38 30.91,11.81 33.89,11.37C36.81,10.94 39.76,10.64 42.71,10.58C48.27,10.46 54.18,11.25 58.92,14.38C62.84,16.97 65.95,21.29 66.57,26.01C66.87,28.39 66.47,30.82 65.35,32.95C64.17,35.18 62.35,37.02 60.32,38.5C58.14,40.08 55.74,41.33 53.29,42.44C50.46,43.72 47.53,44.78 44.53,45.63C38.6,47.31 32.49,48.06 26.33,48C24.87,47.99 23.47,48.06 22.12,48.64C21.21,49.04 22,50.37 22.9,49.98C24.35,49.35 26.05,49.56 27.59,49.56C29.14,49.55 30.69,49.49 32.24,49.37C35.41,49.13 38.56,48.65 41.66,47.95C47.61,46.61 53.58,44.46 58.84,41.32C63.35,38.62 67.43,34.66 68.11,29.21C68.73,24.28 66.44,19.36 63.08,15.86C59.13,11.75 53.61,9.83 48.04,9.24C41.98,8.59 35.7,9.34 29.74,10.51C23.88,11.66 18.1,13.69 13.41,17.5C9.62,20.58 6.55,24.89 5.78,29.79C5.13,33.93 5.55,38.67 7.8,42.3C8.34,43.17 9,43.98 9.78,44.64C10.13,44.94 10.5,45.21 10.88,45.45C11.39,45.75 12,45.94 12.46,46.31C13.01,46.75 12.56,47.46 12.36,47.99C12.05,48.82 11.73,49.65 11.42,50.47C10.8,52.09 10.19,53.71 9.58,55.33C8.98,56.92 8.38,58.5 7.78,60.08C7.42,61.02 8.91,61.4 9.27,60.49C9.73,59.33 10.73,58.38 11.63,57.56C12.65,56.64 13.75,55.82 14.89,55.07C16.16,54.23 17.43,53.4 18.68,52.54C20.04,51.6 21.41,50.68 22.9,49.98C23.8,49.56 23.02,48.22 22.12,48.64Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M93.38,63.98C93.45,61.22 92.78,58.38 91.14,56.17C88.29,52.32 83.12,51.01 78.34,50.81C67.92,50.37 57.39,54.13 49.6,61.07C42.36,67.53 41.26,77.29 51.67,81.2C55.28,82.55 59.24,82.66 63.1,82.56C64.67,82.52 70.61,80.69 71.18,81.85C73.18,85.9 77.02,88.99 81.4,90.07C79.26,87.3 78.35,83.62 78.96,80.17C79.01,79.88 87.28,76.09 88.38,75.09C91.45,72.32 93.28,68.1 93.38,63.98Z"
android:fillColor="#332E36"/>
<path
android:pathData="M94.15,63.97C94.24,59.6 92.53,55.43 88.82,52.95C85.49,50.72 81.3,50.07 77.38,50.01C68.62,49.86 59.81,52.6 52.66,57.66C49.61,59.82 46.7,62.36 44.9,65.7C43.49,68.31 42.78,71.4 43.57,74.33C44.41,77.48 46.89,79.82 49.75,81.21C51.86,82.24 54.12,82.81 56.44,83.1C58.67,83.38 61.04,83.51 63.29,83.32C64.58,83.21 65.86,82.86 67.13,82.61C67.83,82.47 68.53,82.34 69.24,82.28C69.53,82.25 69.82,82.23 70.11,82.24C70.33,82.25 70.46,82.28 70.57,82.3C70.46,82.29 70.6,82.29 70.6,82.32C70.62,82.4 70.49,82.2 70.49,82.2C70.51,82.34 70.69,82.58 70.76,82.71C71.01,83.17 71.28,83.62 71.58,84.06C72.14,84.89 72.78,85.67 73.48,86.38C74.88,87.8 76.55,88.99 78.36,89.81C79.27,90.23 80.22,90.57 81.19,90.82C81.78,90.97 82.5,90.25 82.06,89.68C80.24,87.28 79.34,84.31 79.58,81.31C79.6,81.12 79.62,80.94 79.64,80.75L79.67,80.57C79.73,80.33 79.71,80.32 79.61,80.53C79.27,80.81 79.53,80.71 79.55,80.66C79.49,80.78 79.39,80.77 79.49,80.71C79.69,80.61 79.87,80.49 80.07,80.38C80.71,80.04 81.37,79.71 82.03,79.38C83.72,78.53 85.41,77.71 87.07,76.81C87.6,76.52 88.14,76.23 88.63,75.87C89.6,75.15 90.41,74.14 91.11,73.16C93,70.49 94.05,67.24 94.15,63.97C94.19,62.98 92.64,62.98 92.61,63.97C92.52,66.92 91.56,69.81 89.88,72.23C89.49,72.78 89.07,73.29 88.61,73.78C88.36,74.05 88.1,74.3 87.83,74.55C87.79,74.58 87.67,74.67 87.85,74.54C87.8,74.57 87.76,74.6 87.72,74.63C87.13,75.01 86.53,75.35 85.91,75.67C84.24,76.56 82.54,77.39 80.85,78.24C80.23,78.56 79.6,78.86 79,79.21C78.82,79.31 78.63,79.41 78.48,79.55C78.11,79.9 78.13,80.46 78.07,80.93C77.7,84.28 78.69,87.78 80.73,90.46L81.6,89.33C77.92,88.39 74.65,86.05 72.62,82.84C72.25,82.25 72,81.36 71.38,80.99C70.96,80.73 70.41,80.69 69.92,80.69C68.57,80.7 67.2,81.02 65.88,81.29C64.57,81.55 63.51,81.78 62.24,81.8C59.91,81.84 57.56,81.79 55.27,81.37C51.87,80.75 48.14,79.28 46.15,76.3C42.64,71.05 46.48,64.79 50.58,61.24C56.88,55.79 64.97,52.42 73.26,51.7C77.17,51.36 81.28,51.45 85.01,52.78C86.7,53.37 88.31,54.28 89.59,55.55C91.05,57.01 91.95,58.9 92.36,60.92C92.56,61.92 92.63,62.95 92.61,63.97C92.59,64.97 94.14,64.97 94.15,63.97Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M18.55,34.7C22.93,33.35 25.61,28.16 24.04,23.82C23.91,23.46 23.5,23.11 23.09,23.28C20.25,24.45 20.36,28.39 22.68,30.03C25.71,32.18 29.45,30.26 31.87,28.17C33.05,27.16 35.43,25.29 34.16,23.52C33.69,22.86 32.43,23.22 32.75,24.11C33.32,25.7 35.12,25.74 36.55,25.84C38.45,25.96 40.36,25.96 42.27,25.83C46.04,25.57 49.78,24.83 53.36,23.62C54.3,23.31 53.89,21.81 52.95,22.13C49.77,23.21 46.47,23.92 43.13,24.22C41.48,24.36 39.82,24.41 38.17,24.37C37.34,24.34 36.51,24.3 35.68,24.22C35.28,24.19 34.41,24.16 34.24,23.7L32.83,24.3C33.26,24.89 32.34,25.67 31.94,26.04C31.32,26.61 30.7,27.18 30.03,27.69C28.77,28.66 27.32,29.42 25.7,29.4C24.44,29.37 23.01,28.81 22.6,27.52C22.3,26.59 22.48,25.19 23.5,24.77L22.55,24.23C23.82,27.76 21.76,32.09 18.14,33.21C17.19,33.51 17.59,35 18.55,34.7Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M29.49,39.62C30.99,40.46 32.89,40.32 34.21,39.2C35.49,38.11 35.92,36.16 35.28,34.62C35.11,34.21 34.6,33.84 34.15,34.16C32.81,35.1 33.15,37.04 34.39,37.91C35.89,38.96 37.84,38.48 39.45,37.98C43.41,36.74 47.27,35.17 50.98,33.33C51.88,32.89 51.09,31.55 50.2,31.99C47.26,33.45 44.22,34.73 41.11,35.8C39.76,36.27 38.28,36.92 36.83,36.98C36.25,37.01 35.55,36.95 35.12,36.51C34.94,36.33 34.62,35.71 34.93,35.5L33.79,35.03C34.21,36.04 34.07,37.24 33.24,38C32.43,38.73 31.2,38.81 30.27,38.28C29.4,37.79 28.62,39.13 29.49,39.62Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M59.25,72.04C60.72,70.95 61.82,69.46 62.38,67.7C62.63,66.89 62.88,65.87 62.7,65.02C62.51,64.14 61.63,63.63 60.8,64.1C59.4,64.9 59.35,66.89 60.14,68.14C61.11,69.67 63.09,69.98 64.7,69.35C66.77,68.54 67.88,66.59 68.7,64.65L67.83,65C68.19,65.07 68.36,65.68 68.56,65.99C68.85,66.46 69.24,66.85 69.73,67.11C70.72,67.65 71.91,67.69 73,67.55C75.91,67.19 78.8,66.14 81.47,64.96C82.37,64.56 81.59,63.23 80.69,63.63C79.38,64.21 78.03,64.7 76.66,65.12C75.42,65.49 74.13,65.87 72.84,66.02C71.99,66.13 70.89,66.16 70.19,65.57C69.43,64.92 69.4,63.73 68.24,63.51C67.94,63.45 67.5,63.54 67.36,63.87C66.75,65.31 66.02,66.91 64.59,67.71C63.48,68.32 61.79,68.35 61.28,66.97C61.19,66.73 61.14,66.47 61.16,66.22C61.19,65.94 61.38,65.79 61.43,65.55C61.59,65.46 61.56,65.4 61.36,65.38C61.21,65.26 61.16,65.26 61.19,65.36C61.16,65.4 61.19,65.67 61.19,65.74C61.16,66.15 61.09,66.55 60.98,66.95C60.59,68.43 59.71,69.79 58.47,70.71C57.68,71.3 58.45,72.64 59.25,72.04Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M67.86,74.39C69.45,74.3 71.05,74.21 72.65,74.11C73.05,74.09 73.44,73.77 73.42,73.34C73.4,72.94 73.08,72.54 72.65,72.57C71.05,72.66 69.45,72.76 67.86,72.85C67.46,72.87 67.07,73.19 67.09,73.62C67.1,74.02 67.43,74.42 67.86,74.39Z"
android:fillColor="#F3F2F3"/>
<path
android:pathData="M35.88,71.47C36.24,71.84 36.83,71.84 37.19,71.47L36.54,70.82C37.19,71.47 37.19,71.47 37.19,71.47L37.2,71.47L37.2,71.47L37.2,71.47L37.22,71.45C37.23,71.43 37.25,71.41 37.28,71.39C37.33,71.33 37.4,71.25 37.49,71.15C37.68,70.96 37.92,70.67 38.21,70.32C38.77,69.62 39.48,68.63 40.05,67.5C40.61,66.39 41.06,65.06 41,63.7C40.95,62.3 40.36,60.94 38.98,59.84C36.24,57.65 33.35,58.31 31.32,59.39C30.31,59.93 29.46,60.59 28.87,61.11C28.58,61.37 28.34,61.6 28.18,61.77C28.1,61.85 28.03,61.92 27.99,61.96C27.97,61.99 27.95,62.01 27.94,62.02L27.92,62.04L27.92,62.04L27.92,62.04L27.92,62.05C27.92,62.05 27.92,62.05 28.61,62.66L27.92,62.05C27.58,62.43 27.61,63.02 28,63.36C28.39,63.7 28.97,63.66 29.31,63.28L29.31,63.28L29.31,63.28L29.32,63.27C29.33,63.26 29.34,63.25 29.36,63.23C29.39,63.19 29.44,63.14 29.51,63.07C29.64,62.93 29.85,62.74 30.1,62.51C30.62,62.05 31.35,61.49 32.2,61.04C33.89,60.14 35.9,59.76 37.82,61.29C38.77,62.05 39.11,62.9 39.14,63.77C39.18,64.69 38.87,65.69 38.38,66.67C37.9,67.64 37.27,68.51 36.76,69.15C36.5,69.47 36.28,69.73 36.12,69.9C36.04,69.99 35.98,70.05 35.93,70.1C35.91,70.12 35.9,70.13 35.89,70.14L35.88,70.15L35.88,70.16L35.88,70.16C35.51,70.52 35.51,71.11 35.88,71.47ZM19.49,72.4C19.12,72.04 18.53,72.04 18.17,72.4L18.83,73.06C18.17,72.4 18.17,72.4 18.17,72.4L18.17,72.41L18.17,72.41L18.16,72.41L18.14,72.43C18.13,72.44 18.11,72.47 18.08,72.49C18.03,72.55 17.96,72.62 17.87,72.72C17.69,72.92 17.44,73.2 17.16,73.56C16.59,74.26 15.88,75.25 15.32,76.37C14.76,77.49 14.31,78.82 14.36,80.17C14.41,81.58 15,82.94 16.38,84.04C19.12,86.23 22.01,85.57 24.04,84.49C25.06,83.95 25.9,83.29 26.49,82.77C26.79,82.51 27.02,82.28 27.18,82.11C27.27,82.03 27.33,81.96 27.37,81.91C27.4,81.89 27.41,81.87 27.43,81.86L27.44,81.84L27.45,81.84L27.45,81.83L27.45,81.83C27.45,81.83 27.45,81.83 26.75,81.22L27.45,81.83C27.79,81.45 27.75,80.86 27.36,80.52C26.98,80.18 26.39,80.21 26.05,80.6L26.05,80.6L26.05,80.6L26.04,80.61C26.04,80.62 26.02,80.63 26.01,80.65C25.97,80.68 25.92,80.74 25.86,80.81C25.72,80.94 25.52,81.14 25.26,81.37C24.74,81.83 24.02,82.39 23.17,82.84C21.47,83.74 19.47,84.12 17.55,82.59C16.6,81.83 16.26,80.97 16.22,80.1C16.19,79.19 16.49,78.18 16.98,77.21C17.47,76.24 18.09,75.36 18.61,74.72C18.86,74.41 19.09,74.15 19.25,73.98C19.33,73.89 19.39,73.83 19.43,73.78C19.45,73.76 19.47,73.74 19.48,73.73L19.49,73.72L19.49,73.72L19.49,73.72C19.85,73.36 19.85,72.77 19.49,72.4ZM15.19,65.46C15.4,64.99 15.95,64.78 16.42,64.99L21.55,67.32C22.01,67.54 22.22,68.09 22.01,68.56C21.8,69.03 21.24,69.23 20.77,69.02L15.65,66.69C15.18,66.48 14.97,65.92 15.19,65.46ZM39.85,79.74C40.32,79.95 40.87,79.74 41.09,79.27C41.3,78.8 41.09,78.25 40.62,78.04L35.5,75.71C35.03,75.5 34.48,75.7 34.26,76.17C34.05,76.64 34.26,77.19 34.73,77.41L39.85,79.74ZM20.07,59C20.5,58.72 21.08,58.85 21.35,59.28L24.38,64.03C24.66,64.46 24.53,65.04 24.09,65.32C23.66,65.59 23.08,65.47 22.81,65.03L19.78,60.29C19.5,59.85 19.63,59.28 20.07,59ZM34.92,85.44C35.2,85.88 35.77,86.01 36.21,85.73C36.64,85.45 36.77,84.88 36.49,84.44L33.47,79.7C33.19,79.26 32.61,79.13 32.18,79.41C31.75,79.69 31.62,80.26 31.89,80.7L34.92,85.44Z"
android:fillColor="#F3F2F3"
android:fillType="evenOdd"/>
<path
android:pathData="M83.66,29.18C83.91,29.29 84.21,29.17 84.32,28.92L83.85,28.72C84.32,28.92 84.32,28.92 84.32,28.92L84.32,28.92L84.32,28.91L84.32,28.91L84.32,28.9C84.33,28.89 84.33,28.87 84.34,28.86C84.35,28.82 84.38,28.76 84.4,28.7C84.45,28.56 84.52,28.37 84.59,28.14C84.73,27.67 84.88,27.03 84.94,26.36C84.99,25.69 84.94,24.93 84.64,24.27C84.33,23.58 83.76,23.02 82.85,22.75C81.04,22.21 79.73,23.13 78.94,24.08C78.54,24.55 78.25,25.05 78.06,25.43C77.97,25.62 77.9,25.78 77.85,25.9C77.83,25.95 77.81,26 77.8,26.03C77.79,26.05 77.78,26.06 77.78,26.07L77.78,26.08L77.78,26.09L77.77,26.09L77.77,26.09C77.77,26.09 77.77,26.09 78.25,26.26L77.77,26.09C77.68,26.35 77.82,26.64 78.08,26.73C78.34,26.82 78.63,26.68 78.72,26.42L78.72,26.42L78.72,26.42L78.72,26.42L78.73,26.39C78.74,26.36 78.76,26.33 78.78,26.28C78.82,26.18 78.88,26.04 78.96,25.88C79.13,25.54 79.38,25.12 79.71,24.72C80.37,23.93 81.29,23.33 82.56,23.71C83.19,23.9 83.54,24.25 83.73,24.68C83.93,25.13 83.98,25.69 83.93,26.28C83.89,26.86 83.75,27.42 83.63,27.85C83.56,28.06 83.5,28.23 83.46,28.35C83.44,28.41 83.42,28.45 83.41,28.48L83.39,28.52L83.39,28.52L83.39,28.53L83.39,28.53C83.28,28.78 83.4,29.08 83.66,29.18ZM75.67,32.97C75.41,32.86 75.12,32.98 75.01,33.23L75.47,33.43C75.01,33.23 75.01,33.23 75.01,33.23L75.01,33.23L75.01,33.24L75.01,33.24L75,33.25C75,33.26 74.99,33.28 74.98,33.3C74.97,33.33 74.95,33.39 74.92,33.45C74.87,33.59 74.81,33.78 74.74,34.01C74.6,34.48 74.44,35.12 74.39,35.79C74.33,36.46 74.38,37.22 74.68,37.88C74.99,38.57 75.56,39.13 76.47,39.4C78.28,39.94 79.59,39.02 80.39,38.07C80.78,37.6 81.07,37.1 81.26,36.72C81.36,36.53 81.43,36.37 81.47,36.25C81.5,36.2 81.52,36.15 81.53,36.12C81.53,36.1 81.54,36.09 81.54,36.08L81.55,36.07L81.55,36.06L81.55,36.06L81.55,36.06C81.55,36.06 81.55,36.06 81.07,35.89L81.55,36.06C81.64,35.8 81.5,35.51 81.24,35.42C80.98,35.33 80.69,35.47 80.6,35.73L80.6,35.73L80.6,35.73L80.6,35.73L80.59,35.76C80.58,35.79 80.57,35.82 80.55,35.87C80.51,35.97 80.44,36.11 80.36,36.27C80.2,36.61 79.95,37.03 79.62,37.43C78.95,38.22 78.03,38.82 76.76,38.44C76.13,38.25 75.79,37.9 75.59,37.47C75.39,37.02 75.34,36.46 75.39,35.87C75.43,35.29 75.57,34.73 75.7,34.3C75.76,34.09 75.82,33.92 75.86,33.8C75.89,33.74 75.9,33.7 75.92,33.67L75.93,33.63L75.93,33.63L75.93,33.62L75.93,33.62C76.04,33.37 75.92,33.07 75.67,32.97ZM72.11,30.37C72.12,30.09 72.36,29.88 72.63,29.89L75.66,30.01C75.94,30.03 76.16,30.26 76.14,30.54C76.13,30.81 75.9,31.03 75.62,31.02L72.59,30.89C72.32,30.88 72.1,30.65 72.11,30.37ZM87.31,32.5C87.59,32.51 87.83,32.3 87.84,32.02C87.85,31.74 87.63,31.51 87.36,31.5L84.33,31.37C84.05,31.36 83.82,31.58 83.8,31.85C83.79,32.13 84.01,32.37 84.28,32.38L87.31,32.5ZM73.24,26.16C73.4,25.93 73.71,25.88 73.94,26.04L76.41,27.8C76.64,27.96 76.69,28.27 76.53,28.5C76.37,28.72 76.06,28.78 75.83,28.62L73.36,26.86C73.13,26.7 73.08,26.38 73.24,26.16ZM86.01,36.35C86.24,36.51 86.55,36.46 86.71,36.23C86.87,36.01 86.82,35.69 86.59,35.53L84.12,33.78C83.89,33.62 83.58,33.67 83.42,33.89C83.26,34.12 83.31,34.43 83.54,34.59L86.01,36.35Z"
android:fillColor="#F3F2F3"
android:fillType="evenOdd"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="40"
android:viewportHeight="40">
<path
android:pathData="M14.01,21.857C14.012,21.908 14.005,21.958 13.987,22.006C13.969,22.054 13.942,22.097 13.907,22.134C13.872,22.171 13.83,22.2 13.783,22.22C13.736,22.24 13.686,22.251 13.635,22.251H9.499C9.329,22.251 9.165,22.194 9.032,22.089C8.899,21.984 8.806,21.837 8.767,21.672C8.743,21.559 8.744,21.443 8.771,21.33C8.797,21.218 8.848,21.113 8.919,21.022C9.581,20.145 10.459,19.454 11.467,19.017C11.024,18.614 10.685,18.11 10.477,17.548C10.269,16.986 10.199,16.382 10.272,15.788C10.345,15.193 10.56,14.624 10.898,14.13C11.236,13.635 11.688,13.229 12.215,12.945C12.743,12.66 13.331,12.507 13.93,12.497C14.529,12.486 15.122,12.62 15.659,12.886C16.196,13.152 16.661,13.543 17.016,14.026C17.371,14.508 17.604,15.069 17.698,15.661C17.71,15.741 17.696,15.822 17.657,15.893C17.619,15.963 17.558,16.02 17.485,16.053C16.445,16.534 15.564,17.302 14.946,18.267C14.328,19.233 14,20.355 13.998,21.501C13.998,21.621 13.998,21.739 14.01,21.857ZM31.072,21.022C30.412,20.145 29.536,19.455 28.53,19.017C28.972,18.614 29.312,18.11 29.52,17.548C29.728,16.986 29.798,16.382 29.725,15.788C29.652,15.193 29.437,14.624 29.099,14.13C28.761,13.635 28.309,13.229 27.782,12.945C27.254,12.66 26.666,12.507 26.067,12.497C25.468,12.486 24.875,12.62 24.338,12.886C23.802,13.152 23.336,13.543 22.981,14.026C22.627,14.508 22.393,15.069 22.299,15.661C22.287,15.741 22.301,15.822 22.34,15.893C22.378,15.963 22.439,16.02 22.512,16.053C23.552,16.534 24.433,17.302 25.051,18.267C25.669,19.233 25.998,20.355 25.999,21.501C25.999,21.621 25.999,21.739 25.987,21.857C25.985,21.908 25.993,21.958 26.01,22.006C26.028,22.054 26.055,22.097 26.09,22.134C26.125,22.171 26.168,22.2 26.214,22.22C26.261,22.24 26.311,22.251 26.362,22.251H30.499C30.668,22.251 30.832,22.194 30.965,22.089C31.098,21.984 31.191,21.837 31.23,21.672C31.254,21.559 31.253,21.442 31.226,21.33C31.2,21.217 31.149,21.112 31.077,21.022H31.072ZM22.729,25.07C23.475,24.498 24.024,23.706 24.298,22.806C24.571,21.906 24.556,20.943 24.254,20.053C23.952,19.162 23.379,18.388 22.615,17.84C21.85,17.292 20.933,16.997 19.993,16.997C19.052,16.997 18.135,17.292 17.37,17.84C16.606,18.388 16.032,19.162 15.731,20.053C15.429,20.943 15.413,21.906 15.687,22.806C15.961,23.706 16.51,24.498 17.256,25.07C15.931,25.644 14.825,26.627 14.099,27.876C14.033,27.99 13.998,28.119 13.998,28.251C13.998,28.382 14.033,28.512 14.099,28.626C14.165,28.74 14.259,28.834 14.373,28.9C14.488,28.966 14.617,29.001 14.748,29.001H25.249C25.38,29.001 25.51,28.966 25.624,28.9C25.738,28.834 25.832,28.74 25.898,28.626C25.964,28.512 25.999,28.382 25.999,28.251C25.999,28.119 25.964,27.99 25.898,27.876C25.171,26.626 24.062,25.643 22.735,25.07H22.729Z"
android:fillColor="#FFFFFD"/>
</vector>

View File

@ -157,6 +157,7 @@
<string name="channel_age_gate_dob_too_young">يجب أن يكون عمرك 18 عاما أو أكثر لعرض هذه القناة.</string>
<string name="channel_age_gate_dob_invalid_future">لا يمكنك أن تولد في المستقبل.</string>
<string name="direct_messages">الرسائل الخاصة</string>
<string name="discover_servers">اكتشف الخوادم</string>
<string name="channel_dm">رسالة خاصة</string>
<string name="channel_text">قناة نصية</string>
<string name="channel_voice">قناة صوتية</string>

View File

@ -171,6 +171,7 @@
<string name="no_active_channel_body">Vyberte si server zleva a začněte. Pokud se cítíte odvážně, můžete si vytvořit nový server.</string>
<string name="avatar_alt">Avatar uživatele %1$s</string>
<string name="direct_messages">Přímé zprávy</string>
<string name="discover_servers">Prozkoumat servery</string>
<string name="channel_notes">Poznámky</string>
<string name="start_of_conversation">Toto je začátek vaší konverzace</string>
<string name="message_field_placeholder_text">Zpráva #%1$s</string>

View File

@ -215,6 +215,7 @@
<string name="time_rift_heading">Möglicherweise fehlen an dieser Stelle Nachrichten.</string>
<string name="reply_message_not_cached">Unbekannte Nachricht</string>
<string name="direct_messages">Direktnachrichten</string>
<string name="discover_servers">Server entdecken</string>
<string name="login_onboarding_heading">Finde deine Community und verbinde dich mit der Welt.</string>
<string name="message_field_decoration_trusted_moderation_bot">Verifizierter Moderationsbot</string>
<string name="message_field_denied_generic">Du kannst in diesem Kanal keine Nachrichten senden.</string>

View File

@ -216,6 +216,7 @@
<string name="terms_of_service">Términos de servicio</string>
<string name="community_guidelines">Directivas de comunidad</string>
<string name="direct_messages">Mensajes Directos</string>
<string name="discover_servers">Descubrir servidores</string>
<string name="oss_attribution_body_2">Le damos las gracias a los desarrolladores de esos proyectos por hacer disponible su trabajo para todo el mundo.</string>
<string name="system_message_channel_icon_changed_alt">Icono del canal cambiado</string>
<string name="system_message_channel_description_changed_alt">Descripción del canal cambiada</string>

View File

@ -197,6 +197,7 @@
<string name="register_form_heading">Mennään laittamaan sinut kuntoon.</string>
<string name="mfa_interstitial_lead">Sinulla on kaksivaiheinen todennus päällä että tilisi pystyy turvallisena.</string>
<string name="direct_messages">Yksityisviestit</string>
<string name="discover_servers">Löydä palvelimia</string>
<string name="channel_dm">Yksityisviesti</string>
<string name="scroll_to_bottom">Siirry alas</string>
<string name="report_message">Kiitoksia että raportoit tämän viestin. Anna syy viestin raportoinnille.</string>

View File

@ -36,6 +36,7 @@
<string name="media_viewer_title_video">%1$s</string>
<string name="media_viewer_share_audio">Partager l\'audio</string>
<string name="direct_messages">Messages directs</string>
<string name="discover_servers">Découvrir des serveurs</string>
<string name="message_field_placeholder_group">Envoyer un message dans %1$s</string>
<string name="message_field_placeholder_notes">Ajouter une note</string>
<string name="reply_message_empty_has_attachments">Pièces jointes envoyées</string>

View File

@ -199,6 +199,7 @@
<string name="no_active_channel">Nisi u kanalu trenutno.</string>
<string name="avatar_alt">%1$s korisnička slika</string>
<string name="direct_messages">Privatne poruke</string>
<string name="discover_servers">Otkrij servere</string>
<string name="channel_dm">Privatna poruka</string>
<string name="channel_text">Tekstni kanal</string>
<string name="channel_voice">Govorni kanal</string>

View File

@ -66,6 +66,7 @@
<string name="no_active_channel_body">Kezdésnek válassz ki egy szervert balról. Ha merész vagy, hozz létre egy új szervert!</string>
<string name="avatar_alt">%1$s profilképe</string>
<string name="direct_messages">Közvetlen üzenetek</string>
<string name="discover_servers">Szerverek felfedezése</string>
<string name="channel_dm">Közvetlen üzenet</string>
<string name="channel_text">Szövegcsatorna</string>
<string name="channel_voice">Beszédcsatorna</string>

View File

@ -199,6 +199,7 @@
<string name="settings_appearance_theme_amoled">Hitam Murni</string>
<string name="invite_error_no_invite">Kode undangan tidak ditentukan.</string>
<string name="direct_messages">Pesan Langsung</string>
<string name="discover_servers">Temukan Server</string>
<string name="lets_go">Mari mulai</string>
<string name="community_guidelines">Pedoman Komunitas</string>
<string name="reply_message_empty_has_attachments">Kirimkan lampiran</string>

View File

@ -243,6 +243,7 @@
<string name="channel_age_gate_dob_invalid_unlikely">Non puoi essere nato prima %1$d. Dovresti essere morto/a adesso.</string>
<string name="avatar_alt">avatar di %1$s</string>
<string name="direct_messages">Messaggi Diretti</string>
<string name="discover_servers">Scopri server</string>
<string name="channel_text">Canale Testuale</string>
<string name="channel_group">Gruppo</string>
<string name="channel_notes">Note</string>

View File

@ -56,6 +56,7 @@
<string name="no_active_channel">あなたは今チャンネルにいません。</string>
<string name="avatar_alt">%1$sのアバター</string>
<string name="direct_messages">ダイレクトメッセージ</string>
<string name="discover_servers">サーバーを探す</string>
<string name="channel_dm">ダイレクトメッセージ</string>
<string name="channel_text">テキストチャンネル</string>
<string name="channel_voice">ボイスチャンネル</string>

View File

@ -210,6 +210,7 @@
<string name="channel_age_gate_dob_invalid_unlikely">Negalite būti gimęs anksčiau nei %1$d.</string>
<string name="avatar_alt">%1$s avataras</string>
<string name="direct_messages">Tiesioginės žinutės</string>
<string name="discover_servers">Atrasti serverius</string>
<string name="channel_dm">Tiesioginė žinutė</string>
<string name="channel_text">Teksto kanalas</string>
<string name="channel_voice">Balso kanalas</string>

View File

@ -121,6 +121,7 @@
<string name="channel_age_gate_dob_invalid_unlikely">Jūs nevarat piedzimt pirms %1$d.</string>
<string name="avatar_alt">%1$s avatars</string>
<string name="direct_messages">Tiešās ziņas</string>
<string name="discover_servers">Atklāt serverus</string>
<string name="channel_text">Teksta kanāls</string>
<string name="channel_voice">Balss kanāls</string>
<string name="channel_group">Grupa</string>

View File

@ -42,4 +42,6 @@
<string name="onboarding_others">Anderen zullen je vinden, herkennen en vermelden met deze naam.</string>
<string name="could_not_log_in_cta_try_again">Probeer opnieuw</string>
<string name="could_not_log_in_cta_logout">Log uit</string>
<string name="direct_messages">Directe berichten</string>
<string name="discover_servers">Ontdek servers</string>
</resources>

View File

@ -67,6 +67,7 @@
<string name="no_active_channel_body">Wybierz serwer z lewej strony, aby rozpocząć. Jeśli masz ochotę na przygodę, możesz utworzyć nowy serwer.</string>
<string name="avatar_alt">Awatar użytkownika %1$s</string>
<string name="direct_messages">Wiadomości bezpośrednie</string>
<string name="discover_servers">Odkryj serwery</string>
<string name="channel_dm">Wiadomość bezpośrednia</string>
<string name="channel_text">Kanał Tekstowy</string>
<string name="channel_voice">Kanał głosowy</string>

View File

@ -216,6 +216,7 @@
<string name="settings_appearance_theme_m3dynamic_unsupported_toast">O Material You não é suportado por este dispositivo.</string>
<string name="onboarding_changeable">Mas se mudares de ideias, podes sempre mudá-lo nas tuas Definições de Utilizador.</string>
<string name="direct_messages">Mensagens diretas</string>
<string name="discover_servers">Descobrir servidores</string>
<string name="about_full_name">Revolt no Android</string>
<string name="about_brought_to_you_by">Trazido a ti com ❤️ pela equipa do Revolt.</string>
<string name="about_tab_version">Versão</string>

View File

@ -26,6 +26,7 @@
<string name="menu">Meniu</string>
<string name="no_active_channel">Nu ești într-un canal acum.</string>
<string name="direct_messages">Mesaje directe</string>
<string name="discover_servers">Descoperă servere</string>
<string name="channel_dm">Mesaj direct</string>
<string name="channel_text">Canal de text</string>
<string name="channel_group">Grup</string>

View File

@ -216,6 +216,7 @@
<string name="settings_appearance_theme_m3dynamic_unsupported">Material You (неподдерживаемая)</string>
<string name="settings_appearance_theme_m3dynamic_unsupported_toast">Material You не поддерживается на вашем устройстве.</string>
<string name="direct_messages">Личные сообщения</string>
<string name="discover_servers">Обзор серверов</string>
<string name="home_join_jenvolt_description">Jenvolt - это место, созданное разработчиками, для всего, что касается приложения Android и многого другого. Поддержка, обратная связь - всё здесь. Возможно, вы сможете опробовать новые функции! 👀</string>
<string name="friends_incoming_requests">Входящие запросы</string>
<string name="message_field_decoration_trusted_moderation_bot">Проверенный бот модерации</string>

View File

@ -216,6 +216,7 @@
<string name="reply_message_empty_has_attachments">Ek dosyalar gönder</string>
<string name="settings_appearance_theme_amoled">Saf Siyah</string>
<string name="direct_messages">Direkt Mesajlar</string>
<string name="discover_servers">Sunucuları Keşfet</string>
<string name="about_tab_version">Sürüm</string>
<string name="emoji_category_food">Yiyecek &amp; İçecek</string>
<string name="emoji_category_travel">Seyahat &amp; Yerler</string>

View File

@ -216,6 +216,7 @@
<string name="back">← Назад</string>
<string name="reply_message_not_cached">Невідоме повідомлення</string>
<string name="direct_messages">Особисті повідомлення</string>
<string name="discover_servers">Знайти сервери</string>
<string name="oss_attribution_body">Revolt побудований за допомогою цих чудових проєктів із відкритим вихідним кодом.</string>
<string name="oss_attribution_generation_date">Останнє оновлення: %1$s</string>
<string name="oss_attribution_body_2">Ми вдячні розробникам цих проєктів за те, що вони зробили свою роботу доступною для світу.</string>

View File

@ -60,6 +60,7 @@
<string name="no_active_channel_body">从左边选择一个服务器就可以开始了。如果您要自己探索,可以创建一个新的服务器。</string>
<string name="avatar_alt">%1$s 的头像</string>
<string name="direct_messages">私人消息</string>
<string name="discover_servers">发现服务器</string>
<string name="channel_dm">私人消息</string>
<string name="channel_text">文字频道</string>
<string name="channel_group">群组</string>

View File

@ -226,6 +226,8 @@
<string name="avatar_alt">%1$s\'s avatar</string>
<string name="direct_messages">Direct Messages</string>
<string name="discover_servers">Discover Servers</string>
<string name="discover_servers_description">Join trending and official groups to be part of something big.</string>
<string name="channel_dm">Direct Message</string>
<string name="channel_text">Text Channel</string>
@ -541,15 +543,17 @@
<string name="link_type_no_intent">No app found to handle this link</string>
<string name="link_open">Open</string>
<string name="invite_message">You\'ve been invited to join this server. Would you like to join?</string>
<string name="invite_join">Join</string>
<string name="invite_cancel">Cancel</string>
<string name="invite_message">Youve been invited to join</string>
<string name="invite_join">Accept Invite</string>
<string name="invite_cancel">No Thanks</string>
<string name="invite_already_member">You are already a member of this server.</string>
<string name="invite_error_header">There was an error</string>
<string name="members_count">%1$d members</string>
<string name="invite_error_header">Link No Longer Valid</string>
<string name="invite_error_no_invite">No invite code was specified.</string>
<string name="invite_error_invalid_invite">Could not find an invite with the specified code.</string>
<string name="invite_error_invalid_invite">This link seems invalid or expired. Reach out for a new invite.</string>
<string name="invite_error_banned">You are banned from this server.</string>
<string name="invite_error_unknown">An unknown error occurred.</string>
<string name="joining">Joining…</string>
<string name="media_viewer_title_image">%1$s</string>
<string name="media_viewer_title_video">%1$s</string>
@ -803,4 +807,9 @@
<string name="geogate_description">Revolt may block content in certain jurisdictions in response to legislation or legal notices</string>
<string name="geogate_description_variant_osa_uk_25" translatable="false">This channel is not available in your region while we review options on legal compliance.</string>
<string name="geogate_acknowledge">Acknowledge</string>
<string name="error">Error</string>
<string name="retry">Retry</string>
<string name="no_servers_found">No Servers Found</string>
<string name="no_servers_description">There are no servers available at the moment. Please try again later.</string>
</resources>