1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-27 09:45:46 +00:00

Compare commits

..

58 Commits

Author SHA1 Message Date
c0a43077ad optimize imports 2020-07-02 16:15:06 +06:00
1811a63a13 update last added sendVenue 2020-07-02 16:00:38 +06:00
cba0e30710 sendVenue with Location 2020-07-02 15:55:14 +06:00
ff0b7faa48 Foursquare and fixes of deprecations in methods 2020-07-02 00:52:52 +06:00
975898660c TelegramBotAPI Venue and foursquare additions 2020-07-01 23:57:20 +06:00
cfb7f35d20 add several makeLinkToMessage 2020-06-27 10:11:03 +06:00
147889a66a update readme 2020-06-27 09:59:57 +06:00
ed9ed715a0 update defaults for new FlowsUpdatesFilter 2020-06-27 09:51:18 +06:00
a9a3f55c8d refactoring of FlowsUpdatesFilter 2020-06-27 09:44:50 +06:00
58943f2504 small refactor of BaseMessagesUpdatesConversations 2020-06-27 09:31:29 +06:00
5f7633a57e start 0.27.8 2020-06-27 09:30:25 +06:00
65cfc3220d add hierarchy diagram 2020-06-26 19:11:59 +06:00
36d30ef91b Merge pull request #92 from InsanusMokrassar/0.27.7
0.27.7
2020-06-26 17:50:05 +06:00
41e5c579a2 add excluding of CHANGELOG file for labeler 2020-06-26 17:45:16 +06:00
bbf63c51ec Revert "add com.soywiz.korlibs.krypto:krypto dependency"
This reverts commit acfb7066d2.
2020-06-25 15:45:38 +06:00
fb91199f83 Revert "start implement passport"
This reverts commit d76c09ffb2.
2020-06-25 15:45:35 +06:00
d76c09ffb2 start implement passport 2020-06-25 15:45:15 +06:00
acfb7066d2 add com.soywiz.korlibs.krypto:krypto dependency 2020-06-25 12:07:48 +06:00
7507c107b4 add one more flatMatrix 2020-06-24 20:54:22 +06:00
2acb177ad6 first keyboards improvements 2020-06-24 20:51:48 +06:00
b5a14077fd start 0.27.7 2020-06-24 20:25:51 +06:00
5f60bf003f Add useful links 2020-06-07 17:27:20 +06:00
f9b2c4c403 update README 2020-06-05 17:01:37 +06:00
c909774403 Merge pull request #91 from InsanusMokrassar/0.27.6
0.27.6
2020-06-05 15:44:30 +06:00
670cfcca13 update kotlin coroutines 2020-06-05 15:17:14 +06:00
130e00b62b extensions for CommonMessage 2020-06-05 14:57:58 +06:00
ca4beee95f add PossiblySentViaBotCommonMessage and fix error in build 2020-06-05 14:25:19 +06:00
ca784e67df add BuiltInMimeTypes, ThumbedWithMimeTypeInlineQueryResult and buildMimeType factory 2020-06-05 14:01:19 +06:00
835b8b34f9 add via_bot 2020-06-05 13:40:12 +06:00
e6430a729c work on version 0.27.6 has been started 2020-06-05 13:37:11 +06:00
6c4c9f2fc6 by default dokka task will not set up exact folder for docs 2020-06-03 15:42:00 +06:00
310a7e6e82 update docs build gradle to be able to put dokka where it is required 2020-06-03 15:39:54 +06:00
7375894645 Merge pull request #90 from InsanusMokrassar/0.27.5
0.27.5
2020-06-02 22:26:07 +06:00
69973c597b update BotCommandNameRegex 2020-06-02 22:10:33 +06:00
22e8b06fda BotBuilder fixes 2020-06-02 21:18:49 +06:00
7ede53fdbb BotCommandNameRegex and strict check of incoming command 2020-06-02 20:16:55 +06:00
ca9051920d new setMyCommands extension added 2020-06-02 19:54:13 +06:00
b477e8d585 extend getChat extensions 2020-06-02 13:54:30 +06:00
8ae2f57d55 update description of PreviewFeature annotation 2020-06-02 13:47:28 +06:00
1fb2ecf15f executes was replaced 2020-06-02 13:39:09 +06:00
6073d914d5 hotfixes in new media groups shortcuts 2020-06-02 13:22:36 +06:00
16f55d70af resend and other media group utils replaced into TelegramBotAPI_extensions-utils 2020-06-02 13:21:38 +06:00
b484a31a4a replacement of CaptionAndTextSourcesToText 2020-06-02 13:05:15 +06:00
0a162c4129 StringFormattiing replacement 2020-06-02 01:26:46 +06:00
648f1b488b add makeLinkToAddStickerSet 2020-06-02 01:15:08 +06:00
5fbde4bc06 new "row" 2020-06-02 01:02:38 +06:00
2a276d9272 safely function 2020-06-01 12:56:48 +06:00
9ae252717d versions update 2020-06-01 12:00:06 +06:00
456143a266 complete refresh of CaptinAndTextSourcesToText 2020-06-01 11:55:48 +06:00
0bcc98e126 update caption errors 2020-06-01 11:53:33 +06:00
ab9ceba41c updates in caption and text lengths 2020-06-01 11:44:58 +06:00
7cd5666e88 use maxTextLength inside of CaptionAndTextSourcesToText 2020-05-31 22:53:04 +06:00
35dcd6ada7 fix in SendMessage 2020-05-31 22:51:42 +06:00
ec37df82a9 start 0.27.5 2020-05-31 22:43:35 +06:00
220cb47615 update look like of kdocs badge 2020-05-23 15:46:49 +06:00
d79b8a337a add kdocs badge 2020-05-23 15:43:47 +06:00
cef6a6f741 update telegram badge 2020-05-23 15:27:45 +06:00
9471df1f2d Merge pull request #89 from InsanusMokrassar/0.27.4
0.27.4
2020-05-23 15:22:13 +06:00
73 changed files with 2226 additions and 181 deletions

4
.github/labeler.yml vendored
View File

@@ -4,4 +4,6 @@ core: "TelegramBotAPI/**" # currently not work
code: "**/*.kt"
gradle: "**/*.gradle"
markdown: "**/*.md"
markdown:
- "**/*.md"
- "!CHANGELOG.md"

View File

@@ -49,6 +49,88 @@
* `closePollExactAfter`
* `closePollAfter`
### 0.27.8
* `TelegramBotAPI`:
* `UnknownUpdateType` was renamed to `UnknownUpdate`
* Refactoring and optimization of `FlowsUpdatesFilter`
* `Venue` type was replaced to a new package: `com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue`
* `Venue` type now implements `Locationed` and delegate realisation to its `location` field
* `FoursquareId` and `FoursquareType` typealiases were added
* `TelegramBotAPI-extensions-utils`:
* Several new functions `makeLinkToMessage` was added
* `Foursquare` data class was added
* Extension `Venue#foursquare` was added
* Factory function `Venue` with `Foursquare` parameter was added
### 0.27.7
* `TelegramBotAPI`:
* Operator function `unaryPlus` was added to `RowBuilder`. Now it is possible to write `row { +button }`
* Function `flatMatrix` was added for single-row columns
* Operator extension `RowBuilder#plus` was added to be able to write things like `row { this + button }`
* `TelegramBotAPI-extensions-api`:
* Extensions `RequestsExecutor#sendVenue` with `Location` args were added
* `TelegramBotAPI-extensions-utils`:
* Function `InlineKeyboardMarkup` for flat keyboards was added
* Function `ReplyKeyboardMarkup` for flat keyboards was added
### 0.27.6
* `Common`:
* Versions:
* `Kotlin Coroutines`: `1.3.6` -> `1.3.7`
* `TelegramBotAPI`:
* Interface `PossiblySentViaBot` has been added
* Additional interface `PossiblySentViaBotCommonMessage` was added for more explicit typing declaration for
compiler
* Currently, only `ChannelMessage` and `CommonMessageImpl` are implementing the interface
`PossiblySentViaBotCommonMessage`. It could be changed in future
* Factory `buildMimeType` was added
* `BuiltinMimeTypes` was added
* Abstraction `ThumbedWithMimeTypeInlineQueryResult` with `thumbMimeType` field was added
* `InlineQueryResultGif` and `InlineQueryResultMpeg4Gif` now extend `ThumbedWithMimeTypeInlineQueryResult`
instead of `ThumbedInlineQueryResult`
* `TelegramBotAPI-extensions-utils`:
* New extensions `onlyCommonMessages`, `onlySentViaBot` and `withoutSentViaBot` was added
### 0.27.5
* `Common`:
* Versions:
* `Klock`: `1.11.1` -> `1.11.3`
* `TelegramotAPI`:
* Fix: for sending requests caption and text lengths limits were updated
* New variant of `row` was added
* `makeLinkToMessage` extensions has been deprecated (replaced into `TelegramBotAPI-extensions-utils`)
* Next things was deprecated and replaced into `TelegramBotAPI-extensions-utils`:
* All `String` formatting public extensions and functions
* All extensions like `CaptionedInput#toHtmlCaptions`
* All helper extensions for `List<BaseMessageUpdate>`
* All `RequestsExecutor#executeAsync` and `RequestsExecutor#executeUnsafe`
* `BotCommand` now more strictly check commands which passed to it
* Regex `BotCommandNameRegex` was added
* `TelegramBotAPI-extensions-api`:
* A lot of `RequesstExecutor#getChat` extensions was added for more explicit types showing
* New `RequesstExecutor#setMyCommands` extension was added
* New field `BotBuilder#ktorClientEngineFactory` introduced
* Field `BotBuilder#ktorClientEngine` now is deprecated
* `TelegramBotAPI-extensions-utils`:
* `safely` function was introduced. It is in `PreviewFeature` state currently
* `makeLinkToMessage` extensions has been added
* `makeLinkToAddStickerSet` function and its variations were added
* Next tools was added from `TelegramBotAPI`:
* All `String` formatting extensions and functions
* All extensions like `CaptionedInput#toHtmlCaptions`
* All helper extensions for `List<BaseMessageUpdate>`
* Several new extensions for `SentMediaGroupUpdate` were added:
* `SentMediaGroupUpdate#forwardInfo`
* `SentMediaGroupUpdate#replyTo`
* `SentMediaGroupUpdate#chat`
* `SentMediaGroupUpdate#mediaGroupId`
* Several `List<MediaGroupMessage>.createResend` extensions were added
* `RequestsExecutor#executeAsync` and `RequestsExecutor#executeUnsafe`
### 0.27.4
* `TelegramBotAPI-extensions-utils`:

View File

@@ -1,7 +1,8 @@
# TelegramBotAPI
| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Chat in Telegram](badges/chat.svg)](https://teleg.one/InMoTelegramBotAPI) [![Build Status](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI.svg?branch=master)](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) |
| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI.svg?branch=master)](https://travis-ci.com/InsanusMokrassar/TelegramBotAPI) |
| -------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Useful links | [![Chat in Telegram](badges/chat.svg)](https://teleg.one/InMoTelegramBotAPI) [![KDocs](badges/kdocs.svg)](https://tgbotapi.inmo.dev/docs/index.html) [Examples](https://github.com/InsanusMokrassar/TelegramBotAPI-examples/), [Mini tutorial](https://bookstack.inmo.dev/books/telegrambotapi/chapter/introduction-tutorial) |
| TelegramBotAPI status | [![Download](https://api.bintray.com/packages/insanusmokrassar/StandardRepository/TelegramBotAPI/images/download.svg)](https://bintray.com/insanusmokrassar/StandardRepository/TelegramBotAPI/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI) |
| TelegramBotAPI Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/StandardRepository/TelegramBotAPI-extensions-api/images/download.svg)](https://bintray.com/insanusmokrassar/StandardRepository/TelegramBotAPI-extensions-api/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI-extensions-api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI-extensions-api) |
| TelegramBotAPI Util Extensions status | [![Download](https://api.bintray.com/packages/insanusmokrassar/StandardRepository/TelegramBotAPI-extensions-utils/images/download.svg)](https://bintray.com/insanusmokrassar/StandardRepository/TelegramBotAPI-extensions-utils/_latestVersion) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI-extensions-utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.insanusmokrassar/TelegramBotAPI-extensions-utils) |
@@ -64,6 +65,8 @@ kotlin {
## Ok, where should I start?
![Libraries hierarchy](resources/TelegramBotAPI-libraries-hierarchy.svg)
In most cases, the most simple way will be to implement [TelegramBotAPI All](TelegramBotAPI-all/README.md) - it contains
all necessary tools for comfort usage of this library. If you want to exclude some libraries, you can implement just
[TelegramBotAPI API Extensions](TelegramBotAPI-extensions-api/README.md),

View File

@@ -4,8 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.ProxyConfig
import io.ktor.client.engine.*
/**
* @param proxy Standard ktor [ProxyConfig]
@@ -14,20 +13,30 @@ import io.ktor.client.engine.ProxyConfig
*/
data class BotBuilder internal constructor(
var proxy: ProxyConfig? = null,
@Deprecated("ktorClientEngineFactory parameter will be used preferable. In future this parameter will be removed")
var ktorClientEngine: HttpClientEngine? = null,
var ktorClientEngineFactory: HttpClientEngineFactory<out HttpClientEngineConfig>? = null,
var ktorClientConfig: (HttpClientConfig<*>.() -> Unit) ? = null
) {
internal fun createHttpClient(): HttpClient = ktorClientEngine ?.let { engine ->
internal fun createHttpClient(): HttpClient = ktorClientEngineFactory ?.let {
HttpClient(
it.create {
this@create.proxy = this@BotBuilder.proxy ?: this@create.proxy
}
) {
ktorClientConfig ?.let { it() }
}
} ?: ktorClientEngine ?.let { engine ->
HttpClient(engine) {
ktorClientConfig ?.let { it() }
engine {
proxy = this@BotBuilder.proxy ?: proxy
this@engine.proxy = this@BotBuilder.proxy ?: this@engine.proxy
}
}
} ?: HttpClient {
ktorClientConfig ?.let { it() }
engine {
proxy = this@BotBuilder.proxy ?: proxy
this@engine.proxy = this@BotBuilder.proxy ?: this@engine.proxy
}
}
}

View File

@@ -7,3 +7,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.BotCommand
suspend fun RequestsExecutor.setMyCommands(
commands: List<BotCommand>
) = execute(SetMyCommands(commands))
suspend fun RequestsExecutor.setMyCommands(
vararg commands: BotCommand
) = setMyCommands(commands.toList())

View File

@@ -2,8 +2,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.extensions.api.chat.get
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.requests.chat.get.GetChat
import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.Chat
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.extended.*
import com.github.insanusmokrassar.TelegramBotAPI.utils.PreviewFeature
suspend fun RequestsExecutor.getChat(
chatId: ChatIdentifier
@@ -12,3 +16,117 @@ suspend fun RequestsExecutor.getChat(
suspend fun RequestsExecutor.getChat(
chat: Chat
) = getChat(chat.id)
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedPublicChat] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: PublicChat
) = getChat(chat.id) as ExtendedPublicChat
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedChannelChat] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: ChannelChat
) = getChat(chat.id) as ExtendedChannelChat
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedChannelChatImpl] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: ChannelChatImpl
) = getChat(chat.id) as ExtendedChannelChatImpl
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedGroupChat] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: GroupChat
) = getChat(chat.id) as ExtendedGroupChat
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedGroupChatImpl] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: GroupChatImpl
) = getChat(chat.id) as ExtendedGroupChatImpl
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedSupergroupChat] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: SupergroupChat
) = getChat(chat.id) as ExtendedSupergroupChat
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedSupergroupChatImpl] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: SupergroupChatImpl
) = getChat(chat.id) as ExtendedSupergroupChatImpl
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedPrivateChat] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: PrivateChat
) = getChat(chat.id) as ExtendedPrivateChat
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedPrivateChatImpl] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: PrivateChatImpl
) = getChat(chat.id) as ExtendedPrivateChatImpl
/**
* Will cast incoming [com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat] to a
* [ExtendedUser] with unsafe operator "as"
*
* @throws ClassCastException
*/
@PreviewFeature
suspend fun RequestsExecutor.getChat(
chat: CommonUser
) = getChat(chat.id) as ExtendedUser

View File

@@ -5,6 +5,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.requests.send.SendVenue
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.Chat
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
suspend fun RequestsExecutor.sendVenue(
chatId: ChatIdentifier,
@@ -36,6 +37,32 @@ suspend fun RequestsExecutor.sendVenue(
chat.id, latitude, longitude, title, address, foursquareId, disableNotification, replyToMessageId, replyMarkup
)
suspend fun RequestsExecutor.sendVenue(
chatId: ChatIdentifier,
location: Location,
title: String,
address: String,
foursquareId: String? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
) = sendVenue(
chatId, location.latitude, location.longitude, title, address, foursquareId, disableNotification, replyToMessageId, replyMarkup
)
suspend fun RequestsExecutor.sendVenue(
chat: Chat,
location: Location,
title: String,
address: String,
foursquareId: String? = null,
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null,
replyMarkup: KeyboardMarkup? = null
) = sendVenue(
chat.id, location.latitude, location.longitude, title, address, foursquareId, disableNotification, replyToMessageId, replyMarkup
)
suspend fun RequestsExecutor.sendVenue(
chatId: ChatIdentifier,
venue: Venue,

View File

@@ -76,7 +76,7 @@ fun RequestsExecutor.startGettingFlowsUpdates(
timeoutSeconds: Seconds = 30,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
exceptionsHandler: (suspend (Exception) -> Unit)? = null,
flowsUpdatesFilterUpdatesKeeperCount: Int = 64,
flowsUpdatesFilterUpdatesKeeperCount: Int = 100,
flowUpdatesPreset: FlowsUpdatesFilter.() -> Unit = {}
): FlowsUpdatesFilter = FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply {
flowUpdatesPreset()

View File

@@ -0,0 +1,34 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.PossiblySentViaBotCommonMessage
import kotlinx.coroutines.flow.*
/**
* Simple factory to convert [ContentMessage] to a [CommonMessage]
*/
fun <C: MessageContent, T : ContentMessage<C>> Flow<T>.onlyCommonMessages() = filterIsInstance<CommonMessage<C>>()
/**
* Filter the messages and checking that incoming [CommonMessage] is [PossiblySentViaBotCommonMessage] and its
* [PossiblySentViaBotCommonMessage.senderBot] is not null
*/
fun <T : MessageContent> Flow<CommonMessage<T>>.onlySentViaBot() = mapNotNull {
(it as? PossiblySentViaBotCommonMessage) ?.let { possiblySentViaBot ->
if (possiblySentViaBot.senderBot != null) {
possiblySentViaBot
} else {
null
}
}
}
/**
* Filter the messages and checking that incoming [CommonMessage] not is [PossiblySentViaBotCommonMessage] or its
* [PossiblySentViaBotCommonMessage.senderBot] is null
*/
fun <T : MessageContent> Flow<CommonMessage<T>>.withoutSentViaBot() = filter {
it !is PossiblySentViaBotCommonMessage || it.senderBot == null
}

View File

@@ -0,0 +1,16 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils
import com.github.insanusmokrassar.TelegramBotAPI.utils.*
import kotlinx.coroutines.CoroutineScope
/**
* Shortcut for [handleSafely]. It was created for more comfortable way of handling different things
*/
@PreviewFeature
suspend inline fun <T> safely(
noinline onException: ExceptionHandler<T> = { throw it },
noinline block: suspend CoroutineScope.() -> T
): T = handleSafely(
onException,
block
)

View File

@@ -0,0 +1,26 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.extensions.venue
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
val Venue.foursquare: Foursquare?
get() = foursquareId ?.let {
Foursquare(it, foursquareType)
}
fun Venue(
location: Location,
title: String,
address: String,
foursquare: Foursquare
) = Venue(location, title, address, foursquare.id, foursquare.type)
@Serializable
data class Foursquare(
@SerialName(foursquareIdField)
val id: FoursquareId,
@SerialName(foursquareTypeField)
val type: FoursquareType? = null
)

View File

@@ -0,0 +1,87 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.UsernameChat
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.ExtendedChat
import com.github.insanusmokrassar.TelegramBotAPI.utils.link
private const val internalLinkBeginning = "https://t.me"
fun makeLinkToMessage(
username: String,
messageId: MessageIdentifier
): String = "$internalLinkBeginning/$username/$messageId"
fun makeLinkToMessage(
username: Username,
messageId: MessageIdentifier
): String = makeLinkToMessage(username.username, messageId)
fun makeLinkToMessage(
chat: UsernameChat,
messageId: MessageIdentifier
): String? = chat.username ?.let { makeLinkToMessage(it, messageId) }
private val linkIdRedundantPartRegex = Regex("^-100")
private val usernameBeginSymbolRegex = Regex("^@")
fun makeLinkToMessage(
chat: ExtendedChat,
messageId: MessageIdentifier
): String? {
return when {
chat is UsernameChat && chat.username != null -> {
"$internalLinkBeginning/${chat.username ?.username ?.replace(
usernameBeginSymbolRegex, "")}/$messageId"
}
chat !is PrivateChat -> chat.id.chatId.toString().replace(
linkIdRedundantPartRegex,
""
).let { bareId ->
"$internalLinkBeginning/c/$bareId/$messageId"
}
else -> return null
}
}
private const val stickerSetAddingLinkPrefix = "$internalLinkBeginning/addstickers"
/**
* Create a link for adding of sticker set with name [stickerSetName]. Was added thanks to user Djaler and based on
* https://github.com/Djaler/evil-bot/blob/master/src/main/kotlin/com/github/djaler/evilbot/utils/StickerUtils.kt#L6-L8
*
* @see [makeLinkToAddStickerSetInMarkdownV2]
* @see [makeLinkToAddStickerSetInMarkdown]
* @see [makeLinkToAddStickerSetInHtml]
*/
fun makeLinkToAddStickerSet(
stickerSetName: StickerSetName,
parseMode: ParseMode
) = (stickerSetName to "$stickerSetAddingLinkPrefix/$stickerSetName").link(
parseMode
)
/**
* @return Link for adding of sticker set with name [stickerSetName] with formatting for [MarkdownV2]
*/
fun makeLinkToAddStickerSetInMarkdownV2(stickerSetName: StickerSetName) =
makeLinkToAddStickerSet(
stickerSetName,
MarkdownV2
)
/**
* @return Link for adding of sticker set with name [stickerSetName] with formatting for [Markdown]
*/
fun makeLinkToAddStickerSetInMarkdown(stickerSetName: StickerSetName) =
makeLinkToAddStickerSet(
stickerSetName,
Markdown
)
/**
* @return Link for adding of sticker set with name [stickerSetName] with formatting for [HTML]
*/
fun makeLinkToAddStickerSetInHtml(stickerSetName: StickerSetName) =
makeLinkToAddStickerSet(
stickerSetName,
HTML
)

View File

@@ -0,0 +1,121 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting
import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.fullEntitiesList
fun createFormattedText(
entities: FullTextSourcesList,
partLength: Int = textLength.last,
mode: ParseMode = MarkdownParseMode
): List<String> {
val texts = mutableListOf<String>()
val textBuilder = StringBuilder(partLength)
for (entity in entities) {
val string = when (mode) {
is MarkdownParseMode -> entity.asMarkdownSource
is MarkdownV2ParseMode -> entity.asMarkdownV2Source
is HTMLParseMode -> entity.asHtmlSource
}
if (textBuilder.length + string.length > partLength) {
if (textBuilder.isNotEmpty()) {
texts.add(textBuilder.toString())
textBuilder.clear()
}
val chunked = string.chunked(partLength)
val last = chunked.last()
textBuilder.append(last)
val listToAdd = if (chunked.size > 1) {
chunked.subList(0, chunked.size - 1)
} else {
emptyList()
}
listToAdd.forEach {
texts.add(it)
}
} else {
textBuilder.append(string)
}
}
if (textBuilder.isNotEmpty()) {
texts.add(textBuilder.toString())
textBuilder.clear()
}
return texts
}
fun createMarkdownText(
entities: FullTextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
fun FullTextSourcesList.toMarkdownCaptions(): List<String> = createMarkdownText(
this,
captionLength.last
)
fun CaptionedInput.toMarkdownCaptions(): List<String> = fullEntitiesList().toMarkdownCaptions()
fun FullTextSourcesList.toMarkdownTexts(): List<String> = createMarkdownText(
this,
textLength.last
)
fun TextContent.toMarkdownTexts(): List<String> = fullEntitiesList().toMarkdownTexts()
fun FullTextSourcesList.toMarkdownExplanations(): List<String> = createMarkdownText(
this,
explanationLimit.last
)
fun ExplainedInput.toMarkdownExplanations(): List<String> = fullEntitiesList().toMarkdownTexts()
fun createMarkdownV2Text(
entities: FullTextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
fun FullTextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
this,
captionLength.last
)
fun CaptionedInput.toMarkdownV2Captions(): List<String> = fullEntitiesList().toMarkdownV2Captions()
fun FullTextSourcesList.toMarkdownV2Texts(): List<String> = createMarkdownV2Text(
this,
textLength.last
)
fun TextContent.toMarkdownV2Texts(): List<String> = fullEntitiesList().toMarkdownV2Texts()
fun FullTextSourcesList.toMarkdownV2Explanations(): List<String> = createMarkdownV2Text(
this,
explanationLimit.last
)
fun ExplainedInput.toMarkdownV2Explanations(): List<String> = fullEntitiesList().toMarkdownV2Texts()
fun createHtmlText(
entities: FullTextSourcesList,
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
fun FullTextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
this,
captionLength.last
)
fun CaptionedInput.toHtmlCaptions(): List<String> = fullEntitiesList().toHtmlCaptions()
fun FullTextSourcesList.toHtmlTexts(): List<String> = createHtmlText(
this,
textLength.last
)
fun TextContent.toHtmlTexts(): List<String> = fullEntitiesList().toHtmlTexts()
fun FullTextSourcesList.toHtmlExplanations(): List<String> = createHtmlText(
this,
explanationLimit.last
)
fun ExplainedInput.toHtmlExplanations(): List<String> = fullEntitiesList().toHtmlTexts()

View File

@@ -0,0 +1,243 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.*
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.*
const val markdownBoldControl = "*"
const val markdownItalicControl = "_"
const val markdownCodeControl = "`"
const val markdownPreControl = "```"
const val markdownV2ItalicUnderlineDelimiter = "\u0013"
const val markdownV2StrikethroughControl = "~"
const val markdownV2UnderlineControl = "__"
const val markdownV2UnderlineEndControl = "$markdownV2UnderlineControl$markdownV2ItalicUnderlineDelimiter"
const val markdownV2ItalicEndControl = "$markdownItalicControl$markdownV2ItalicUnderlineDelimiter"
const val htmlBoldControl = "b"
const val htmlItalicControl = "i"
const val htmlCodeControl = "code"
const val htmlPreControl = "pre"
const val htmlUnderlineControl = "u"
const val htmlStrikethroughControl = "s"
private fun String.markdownDefault(
openControlSymbol: String,
closeControlSymbol: String = openControlSymbol
) = "$openControlSymbol${toMarkdown()}$closeControlSymbol"
private fun String.markdownV2Default(
openControlSymbol: String,
closeControlSymbol: String = openControlSymbol,
escapeFun: String.() -> String = String::escapeMarkdownV2Common
) = "$openControlSymbol${escapeFun()}$closeControlSymbol"
private fun String.htmlDefault(
openControlSymbol: String,
closeControlSymbol: String = openControlSymbol
) = "<$openControlSymbol>${toHtml()}</$closeControlSymbol>"
fun String.linkMarkdown(link: String): String = "[${toMarkdown()}](${link.toMarkdown()})"
fun String.linkMarkdownV2(link: String): String = "[${escapeMarkdownV2Common()}](${link.escapeMarkdownV2Link()})"
fun String.linkHTML(link: String): String = "<a href=\"$link\">${toHtml()}</a>"
fun String.boldMarkdown(): String = markdownDefault(markdownBoldControl)
fun String.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl)
fun String.boldHTML(): String = htmlDefault(htmlBoldControl)
fun String.italicMarkdown(): String = markdownDefault(markdownItalicControl)
fun String.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl, markdownV2ItalicEndControl)
fun String.italicHTML(): String = htmlDefault(htmlItalicControl)
/**
* Crutch for support of strikethrough in default markdown. Simply add modifier, but it will not look like correct
*/
fun String.strikethroughMarkdown(): String = map { it + "\u0336" }.joinToString("")
fun String.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl)
fun String.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl)
/**
* Crutch for support of underline in default markdown. Simply add modifier, but it will not look like correct
*/
fun String.underlineMarkdown(): String = map { it + "\u0347" }.joinToString("")
fun String.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl, markdownV2UnderlineEndControl)
fun String.underlineHTML(): String = htmlDefault(htmlUnderlineControl)
fun String.codeMarkdown(): String = markdownDefault(markdownCodeControl)
fun String.codeMarkdownV2(): String = markdownV2Default(markdownCodeControl, escapeFun = String::escapeMarkdownV2PreAndCode)
fun String.codeHTML(): String = htmlDefault(htmlCodeControl)
fun String.preMarkdown(language: String? = null): String = markdownDefault(
"$markdownPreControl${language ?: ""}\n",
"\n$markdownPreControl"
)
fun String.preMarkdownV2(language: String? = null): String = markdownV2Default(
"$markdownPreControl${language ?: ""}\n",
"\n$markdownPreControl",
String::escapeMarkdownV2PreAndCode
)
fun String.preHTML(language: String? = null): String = htmlDefault(
language ?.let {
"$htmlPreControl><$htmlCodeControl class=\"language-$language\""
} ?: htmlPreControl,
language ?.let {
"$htmlCodeControl></$htmlPreControl"
} ?: htmlPreControl
)
fun String.emailMarkdown(): String = linkMarkdown("mailto://$${toMarkdown()}")
fun String.emailMarkdownV2(): String = linkMarkdownV2("mailto://$${toMarkdown()}")
fun String.emailHTML(): String = linkHTML("mailto://$${toHtml()}")
private inline fun String.mention(adapt: String.() -> String): String = if (startsWith("@")) {
adapt()
} else {
"@${adapt()}"
}
private inline fun String.hashTag(adapt: String.() -> String): String = if (startsWith("#")) {
adapt()
} else {
"#${adapt()}"
}
fun String.textMentionMarkdown(userId: UserId): String = linkMarkdown(userId.link)
fun String.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link)
fun String.textMentionHTML(userId: UserId): String = linkHTML(userId.link)
fun String.mentionMarkdown(): String = mention(String::toMarkdown)
fun String.mentionMarkdownV2(): String = mention(String::escapeMarkdownV2Common)
fun String.mentionHTML(): String = mention(String::toHtml)
fun String.hashTagMarkdown(): String = hashTag(String::toMarkdown)
fun String.hashTagMarkdownV2(): String = hashTag(String::escapeMarkdownV2Common).escapeMarkdownV2Common()
fun String.hashTagHTML(): String = hashTag(String::toHtml)
fun String.phoneMarkdown(): String = toMarkdown()
fun String.phoneMarkdownV2(): String = escapeMarkdownV2Common()
fun String.phoneHTML(): String = toHtml()
fun String.command(adapt: String.() -> String): String = if (startsWith("/")) {
adapt()
} else {
"/${adapt()}"
}
fun String.commandMarkdown(): String = command(String::toMarkdown)
fun String.commandMarkdownV2(): String = command(String::escapeMarkdownV2Common)
fun String.commandHTML(): String = command(String::toHtml)
fun String.regularMarkdown(): String = toMarkdown()
fun String.regularMarkdownV2(): String = escapeMarkdownV2Common()
fun String.regularHtml(): String = toHtml()
fun String.cashTagMarkdown(): String = toMarkdown()
fun String.cashTagMarkdownV2(): String = escapeMarkdownV2Common()
fun String.cashTagHtml(): String = toHtml()
infix fun String.bold(parseMode: ParseMode): String = when (parseMode) {
is HTML -> boldHTML()
is Markdown -> boldMarkdown()
is MarkdownV2 -> boldMarkdownV2()
}
infix fun String.italic(parseMode: ParseMode): String = when (parseMode) {
is HTML -> italicHTML()
is Markdown -> italicMarkdown()
is MarkdownV2 -> italicMarkdownV2()
}
infix fun String.hashTag(parseMode: ParseMode): String = when (parseMode) {
is HTML -> hashTagHTML()
is Markdown -> hashTagMarkdown()
is MarkdownV2 -> hashTagMarkdownV2()
}
infix fun String.code(parseMode: ParseMode): String = when (parseMode) {
is HTML -> codeHTML()
is Markdown -> codeMarkdown()
is MarkdownV2 -> codeMarkdownV2()
}
fun String.pre(parseMode: ParseMode, language: String? = null): String = when (parseMode) {
is HTML -> preHTML(language)
is Markdown -> preMarkdown(language)
is MarkdownV2 -> preMarkdownV2(language)
}
infix fun String.pre(parseMode: ParseMode): String = pre(parseMode, null)
infix fun String.email(parseMode: ParseMode): String = when (parseMode) {
is HTML -> emailHTML()
is Markdown -> emailMarkdown()
is MarkdownV2 -> emailMarkdownV2()
}
infix fun Pair<String, String>.link(parseMode: ParseMode): String = when (parseMode) {
is HTML -> first.linkHTML(second)
is Markdown -> first.linkMarkdown(second)
is MarkdownV2 -> first.linkMarkdownV2(second)
}
infix fun String.mention(parseMode: ParseMode): String = when (parseMode) {
is HTML -> mentionHTML()
is Markdown -> mentionMarkdown()
is MarkdownV2 -> mentionMarkdownV2()
}
infix fun Pair<String, ChatId>.mention(parseMode: ParseMode): String = when (parseMode) {
is HTML -> first.textMentionHTML(second)
is Markdown -> first.textMentionMarkdown(second)
is MarkdownV2 -> first.textMentionMarkdownV2(second)
}
infix fun String.phone(parseMode: ParseMode): String = when (parseMode) {
is HTML -> phoneHTML()
is Markdown -> phoneMarkdown()
is MarkdownV2 -> phoneMarkdownV2()
}
infix fun String.command(parseMode: ParseMode): String = when (parseMode) {
is HTML -> commandHTML()
is Markdown -> commandMarkdown()
is MarkdownV2 -> commandMarkdownV2()
}
infix fun String.underline(parseMode: ParseMode): String = when (parseMode) {
is HTML -> underlineHTML()
is Markdown -> underlineMarkdown()
is MarkdownV2 -> underlineMarkdownV2()
}
infix fun String.strikethrough(parseMode: ParseMode): String = when (parseMode) {
is HTML -> strikethroughHTML()
is Markdown -> strikethroughMarkdown()
is MarkdownV2 -> strikethroughMarkdownV2()
}
infix fun String.regular(parseMode: ParseMode): String = when (parseMode) {
is HTML -> regularHtml()
is Markdown -> regularMarkdown()
is MarkdownV2 -> regularMarkdownV2()
}
infix fun String.cashtag(parseMode: ParseMode): String = when (parseMode) {
is HTML -> cashTagHtml()
is Markdown -> cashTagMarkdown()
is MarkdownV2 -> cashTagMarkdownV2()
}

View File

@@ -0,0 +1,57 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendMediaGroup
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.Chat
import com.github.insanusmokrassar.TelegramBotAPI.types.message.ForwardInfo
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.SentMediaGroupUpdate
val List<MediaGroupMessage>.forwardInfo: ForwardInfo?
get() = firstOrNull() ?.forwardInfo
val List<MediaGroupMessage>.replyTo: Message?
get() = firstOrNull() ?.replyTo
val List<MediaGroupMessage>.chat: Chat?
get() = firstOrNull() ?.chat
val List<MediaGroupMessage>.mediaGroupId: MediaGroupIdentifier?
get() = firstOrNull() ?.mediaGroupId
val SentMediaGroupUpdate.forwardInfo: ForwardInfo?
get() = data.first().forwardInfo
val SentMediaGroupUpdate.replyTo: Message?
get() = data.first().replyTo
val SentMediaGroupUpdate.chat: Chat
get() = data.chat!!
val SentMediaGroupUpdate.mediaGroupId: MediaGroupIdentifier
get() = data.mediaGroupId!!
fun List<MediaGroupMessage>.createResend(
chatId: ChatId,
disableNotification: Boolean = false,
replyTo: MessageIdentifier? = null
) = SendMediaGroup(
chatId,
map { it.content.toMediaGroupMemberInputMedia() },
disableNotification,
replyTo
)
fun List<MediaGroupMessage>.createResend(
chat: Chat,
disableNotification: Boolean = false,
replyTo: MessageIdentifier? = null
) = createResend(
chat.id,
disableNotification,
replyTo
)
fun SentMediaGroupUpdate.createResend(
disableNotification: Boolean = false,
replyTo: MessageIdentifier? = null
) = data.createResend(
chat,
disableNotification,
replyTo
)

View File

@@ -0,0 +1,45 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.utils.handleSafely
import kotlinx.coroutines.*
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
scope: CoroutineScope
): Deferred<T> = scope.async {
handleSafely {
execute(request)
}
}
suspend fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>
): Deferred<T> = coroutineScope {
executeAsync(request, this)
}
suspend fun <T: Any> RequestsExecutor.executeUnsafe(
request: Request<T>,
retries: Int = 0,
retriesDelay: Long = 1000L,
onAllFailed: (suspend (exceptions: Array<Exception>) -> Unit)? = null
): T? {
var leftRetries = retries
val exceptions = onAllFailed ?.let { mutableListOf<Exception>() }
do {
return handleSafely(
{
leftRetries--
delay(retriesDelay)
exceptions ?.add(it)
null
}
) {
execute(request)
} ?: continue
} while(leftRetries >= 0)
onAllFailed ?.invoke(exceptions ?.toTypedArray() ?: emptyArray())
return null
}

View File

@@ -0,0 +1,11 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.types.buttons
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardButtons.InlineKeyboardButton
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.utils.flatMatrix
fun InlineKeyboardMarkup(
vararg buttons: InlineKeyboardButton
): InlineKeyboardMarkup = InlineKeyboardMarkup(
flatMatrix { buttons.forEach { +it } }
)

View File

@@ -0,0 +1,17 @@
package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.types.buttons
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardButton
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.ReplyKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.utils.flatMatrix
fun ReplyKeyboardMarkup(
vararg buttons: KeyboardButton,
resizeKeyboard: Boolean? = null,
oneTimeKeyboard: Boolean? = null,
selective: Boolean? = null
): ReplyKeyboardMarkup = ReplyKeyboardMarkup(
flatMatrix { buttons.forEach { +it } },
resizeKeyboard,
oneTimeKeyboard,
selective
)

View File

@@ -3,25 +3,19 @@ package com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.filterIsInstance
fun Flow<Update>.onlyBaseMessageUpdates(): Flow<BaseMessageUpdate> = mapNotNull {
it as? BaseMessageUpdate
}
fun Flow<Update>.onlyBaseMessageUpdates(): Flow<BaseMessageUpdate> = filterIsInstance()
/**
* Converts flow to [Flow] of [BaseSentMessageUpdate]
*/
fun Flow<BaseMessageUpdate>.onlySentMessageUpdates(): Flow<BaseSentMessageUpdate> = mapNotNull {
it as? BaseSentMessageUpdate
}
fun Flow<BaseMessageUpdate>.onlySentMessageUpdates(): Flow<BaseSentMessageUpdate> = filterIsInstance()
/**
* Converts flow to [Flow] of [BaseSentMessageUpdate]
*/
fun Flow<BaseMessageUpdate>.onlyEditMessageUpdates(): Flow<BaseEditMessageUpdate> = mapNotNull {
it as? BaseEditMessageUpdate
}
fun Flow<BaseMessageUpdate>.onlyEditMessageUpdates(): Flow<BaseEditMessageUpdate> = filterIsInstance()
/**
* Converts flow to [Flow] of [MediaGroupUpdate]. Please, remember that it could be either [EditMediaGroupUpdate]
@@ -30,20 +24,14 @@ fun Flow<BaseMessageUpdate>.onlyEditMessageUpdates(): Flow<BaseEditMessageUpdate
* @see onlySentMediaGroupUpdates
* @see onlyEditMediaGroupUpdates
*/
fun Flow<BaseMessageUpdate>.onlyMediaGroupsUpdates(): Flow<MediaGroupUpdate> = mapNotNull {
it as? MediaGroupUpdate
}
fun Flow<BaseMessageUpdate>.onlyMediaGroupsUpdates(): Flow<MediaGroupUpdate> = filterIsInstance()
/**
* Converts flow to [Flow] of [SentMediaGroupUpdate]
*/
fun Flow<MediaGroupUpdate>.onlySentMediaGroupUpdates(): Flow<SentMediaGroupUpdate> = mapNotNull {
it as? SentMediaGroupUpdate
}
fun Flow<MediaGroupUpdate>.onlySentMediaGroupUpdates(): Flow<SentMediaGroupUpdate> = filterIsInstance()
/**
* Converts flow to [Flow] of [EditMediaGroupUpdate]
*/
fun Flow<MediaGroupUpdate>.onlyEditMediaGroupUpdates(): Flow<EditMediaGroupUpdate> = mapNotNull {
it as? EditMediaGroupUpdate
}
fun Flow<MediaGroupUpdate>.onlyEditMediaGroupUpdates(): Flow<EditMediaGroupUpdate> = filterIsInstance()

View File

@@ -8,7 +8,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.updateshandlers.FlowsUpdatesFi
* @see flowsUpdatesFilter
*/
inline fun flowsUpdatesFilter(
internalChannelsSizes: Int = 64,
internalChannelsSizes: Int = 100,
block: FlowsUpdatesFilter.() -> Unit
): FlowsUpdatesFilter {
val filter = FlowsUpdatesFilter(internalChannelsSizes)

View File

@@ -12,6 +12,13 @@ fun <T : BaseSentMessageUpdate> Flow<T>.asContentMessagesFlow() = mapNotNull {
it.data as? ContentMessage<*>
}
/**
* Will map incoming [BaseSentMessageUpdate]s to [CommonMessage] from [BaseSentMessageUpdate.data]
*/
fun <T : BaseSentMessageUpdate> Flow<T>.asCommonMessagesFlow() = mapNotNull {
it.data as? CommonMessage<*>
}
/**
* Will map incoming [BaseSentMessageUpdate]s to [ChatEventMessage] from [BaseSentMessageUpdate.data]
*/

View File

@@ -76,7 +76,7 @@ fun RequestsExecutor.startGettingFlowsUpdatesByLongPolling(
timeoutSeconds: Seconds = 30,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
exceptionsHandler: ExceptionHandler<Unit>? = null,
flowsUpdatesFilterUpdatesKeeperCount: Int = 64,
flowsUpdatesFilterUpdatesKeeperCount: Int = 100,
flowUpdatesPreset: FlowsUpdatesFilter.() -> Unit = {}
): FlowsUpdatesFilter = FlowsUpdatesFilter(flowsUpdatesFilterUpdatesKeeperCount).apply {
flowUpdatesPreset()

View File

@@ -18,7 +18,8 @@ import io.ktor.request.receiveText
import io.ktor.response.respond
import io.ktor.routing.*
import io.ktor.server.engine.*
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.Executors

81
TelegramBotAPI.minder Normal file
View File

@@ -0,0 +1,81 @@
<?xml version="1.0"?>
<minder version="1.8.0">
<theme name="default" label="Default" index="-1"/>
<styles>
<style level="0" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="1" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="2" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="3" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="4" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="5" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="6" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="7" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="8" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="9" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<style level="10" isset="true" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
</styles>
<drawarea x="-53.566975911458371" y="280.97174580891931" scale="1"/>
<images/>
<nodes>
<node id="1" posx="475.27954101562455" posy="-172.96498107910156" maxwidth="489.29239908854163" width="494" height="168" side="top" fold="false" treesize="724" layout="Downwards">
<style linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<formatting/>
<nodename>TelegramBotAPI
Root project with API. It is not recommended to use its requests directly and better to use at least TelegramBotAPI-extensions-api</nodename>
<nodenote></nodenote>
<nodes>
<node id="3" posx="568.77954101562455" posy="95.035018920898438" maxwidth="286.41682942708326" width="307" height="168" side="bottom" fold="false" treesize="724" color="#68b723" colorroot="true" layout="Downwards">
<style linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="none" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<formatting/>
<nodename>TelegramBotAPI-extensions
Family of projects which are fully based on TelegramBotAPI and extend its functionality</nodename>
<nodenote></nodenote>
<nodes>
<node id="5" posx="360.27954101562455" posy="363.03501892089844" maxwidth="322.17146809895831" width="351" height="191" side="bottom" fold="false" treesize="351" color="#68b723" colorroot="true" layout="Downwards">
<style linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<formatting/>
<nodename>TelegramBotAPI-extensions-api
Extensions project for make requests more look like in the Telegram Bot API and give opportunity to use it's easier</nodename>
<nodenote></nodenote>
</node>
<node id="7" posx="711.27954101562455" posy="363.03501892089844" maxwidth="341.10636393229163" width="373" height="145" side="bottom" fold="false" treesize="373" color="#68b723" colorroot="true" layout="Downwards">
<style linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<formatting/>
<nodename>TelegramBotAPI-extensions-utils
Extensions project with utils things which will make easier different operations</nodename>
<nodenote></nodenote>
</node>
</nodes>
</node>
</nodes>
</node>
<node id="9" posx="521.83642578124955" posy="645.92375183105469" maxwidth="405.23974609375" width="395" height="213" side="bottom" fold="false" treesize="395" layout="Downwards">
<style linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<formatting/>
<nodename>TelegramBotAPI-all
Here included all available TelegramBotAPI libraries:&#xD;
&#xD;
* TelegramBotAPI&#xD;
* TelegramBotAPI-extensions-api&#xD;
* TelegramBotAPI-extensions-utils</nodename>
<nodenote></nodenote>
</node>
</nodes>
<connections>
<connection from_id="5" to_id="9" drag_x="574.8447265625" drag_y="605.20840454101562" color="rgb(119,119,119)">
<style connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<title></title>
<note></note>
</connection>
<connection from_id="7" to_id="9" drag_x="856.732666015625" drag_y="600.25286865234375" color="rgb(119,119,119)">
<style connectiondash="dotted" connectionwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10"/>
<title></title>
<note></note>
</connection>
</connections>
</minder>

View File

@@ -10,7 +10,7 @@ moments are describing by official [Telegram Bot API](https://core.telegram.org/
## Compatibility
This version compatible with [24th of April 2020 update of TelegramBotAPI (version 4.8)](https://core.telegram.org/bots/api#april-24-2020).
This version compatible with [4th of June 2020 update of TelegramBotAPI (version 4.9)](https://core.telegram.org/bots/api#june-4-2020).
There is only one exception of implemented functionality - Telegram Passport API, which was presented in
[August 2018 update of TelegramBotAPI](https://core.telegram.org/bots/api-changelog#august-27-2018) update. It will be implemented
as soon as possible.

View File

@@ -13,8 +13,8 @@ import io.ktor.utils.io.core.Closeable
interface RequestsExecutor : Closeable {
/**
* Unsafe execution of incoming [request]. Can throw almost any exception. So, it is better to use
* something like [com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.executeAsync] or
* [com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.executeUnsafe]
* something like [com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.executeAsync] or
* [com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.executeUnsafe]
*
* @throws Exception
*/

View File

@@ -9,6 +9,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
internal val TextContentMessageResultDeserializer: DeserializationStrategy<ContentMessage<TextContent>>
@@ -37,7 +38,7 @@ data class SendTextMessage(
{
init {
if (text.length !in textLength) {
throw IllegalArgumentException("Text must be in $textLength range")
throwRangeError("Text length", textLength, text.length)
}
}

View File

@@ -6,6 +6,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.VenueContent
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
import kotlinx.serialization.*
private val commonResultDeserializer: DeserializationStrategy<ContentMessage<VenueContent>>

View File

@@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.AnimationContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendAnimation(
@@ -93,7 +94,7 @@ data class SendAnimationData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -12,6 +12,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.AudioContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendAudio(
@@ -95,7 +96,7 @@ data class SendAudioData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.DocumentContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendDocument(
@@ -79,7 +80,7 @@ data class SendDocumentData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -8,12 +8,15 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializeOnlySerializerClass
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls
import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.jsonArray
val membersCountInMediaGroup: IntRange = 2 .. 10
@Deprecated("Replaced and renamed", ReplaceWith("mediaCountInMediaGroup", "com.github.insanusmokrassar.TelegramBotAPI.types.mediaCountInMediaGroup"))
val membersCountInMediaGroup
get() = mediaCountInMediaGroup
fun SendMediaGroup(
chatId: ChatIdentifier,
@@ -21,8 +24,8 @@ fun SendMediaGroup(
disableNotification: Boolean = false,
replyToMessageId: MessageIdentifier? = null
): Request<List<MediaGroupMessage>> {
if (media.size !in membersCountInMediaGroup) {
throw IllegalArgumentException("Count of members for media group must be in $membersCountInMediaGroup range")
if (media.size !in mediaCountInMediaGroup) {
throwRangeError("Count of members in media group", mediaCountInMediaGroup, media.size)
}
val files: List<MultipartFile> = media.flatMap {

View File

@@ -10,6 +10,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.PhotoContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendPhoto(
@@ -65,7 +66,7 @@ data class SendPhotoData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.VideoContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendVideo(
@@ -97,7 +98,7 @@ data class SendVideoData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.VideoNoteContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendVideoNote(
@@ -92,7 +93,7 @@ data class SendVideoNoteData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -11,6 +11,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Conten
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.TelegramBotAPIMessageDeserializationStrategyClass
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media.VoiceContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.mapOfNotNull
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.*
fun SendVoice(
@@ -84,7 +85,7 @@ data class SendVoiceData internal constructor(
init {
text ?.let {
if (it.length !in captionLength) {
throw IllegalArgumentException("Caption must be in $captionLength range")
throwRangeError("Caption length", captionLength, it.length)
}
}
}

View File

@@ -1,8 +1,11 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import com.github.insanusmokrassar.TelegramBotAPI.utils.throwRangeError
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
val BotCommandNameRegex = Regex("^[a-z_0-9]{${botCommandLengthLimit.first},${botCommandLengthLimit.last}}$")
@Serializable
data class BotCommand(
@SerialName(botCommandField)
@@ -12,10 +15,13 @@ data class BotCommand(
) {
init {
if (command.length !in botCommandLengthLimit) {
error("Command size must be in range $botCommandLengthLimit, but actually have length ${command.length}")
throwRangeError("Command name size", botCommandLengthLimit, command.length)
}
if (!command.matches(BotCommandNameRegex)) {
error("Bot command must contains only lowercase English letters, digits and underscores, but incoming command was $command")
}
if (description.length !in botCommandDescriptionLimit) {
error("Command description size must be in range $botCommandDescriptionLimit, but actually have length ${description.length}")
throwRangeError("Command description size", botCommandDescriptionLimit, description.length)
}
}
}

View File

@@ -1,5 +1,7 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import com.github.insanusmokrassar.TelegramBotAPI.utils.BuiltinMimeTypes
typealias Identifier = Long
typealias MessageIdentifier = Long
typealias InlineQueryIdentifier = String
@@ -20,14 +22,16 @@ typealias PollIdentifier = String
typealias StickerSetName = String
typealias FileUniqueId = String
typealias DiceResult = Int
typealias FoursquareId = String
typealias FoursquareType = String
typealias Seconds = Int
typealias LongSeconds = Long
val getUpdatesLimit = 1 .. 100
val callbackQueryAnswerLength = 0 until 200
val captionLength = 0 until 1024
val textLength = 0 until 4096
val captionLength = 0 .. 1024
val textLength = 1 .. 4096
val userProfilePhotosRequestLimit = 0 .. 100
val chatTitleLength = 1 until 255
val chatDescriptionLength = 0 until 256
@@ -55,12 +59,20 @@ val botCommandLimit = botCommandLengthLimit
val botCommandDescriptionLimit = 3 .. 256
val botCommandsLimit = 0 .. 100
val mediaCountInMediaGroup: IntRange = 2 .. 10
val explanationLimit = 0 .. 200
@Deprecated("Will be removed in near updates", ReplaceWith("explanationLimit"))
val quizPollExplanationLimit = explanationLimit
val openPeriodPollSecondsLimit = 5 .. 600
val telegramInlineModeGifPermittedMimeTypes = listOf(
BuiltinMimeTypes.Image.Jpg,
BuiltinMimeTypes.Image.Gif,
BuiltinMimeTypes.Video.MP4
)
const val chatIdField = "chat_id"
const val messageIdField = "message_id"
const val updateIdField = "update_id"
@@ -175,6 +187,7 @@ const val stickerFileIdField = "sticker_file_id"
const val gameShortNameField = "game_short_name"
const val thumbUrlField = "thumb_url"
const val thumbMimeTypeField = "thumb_mime_type"
const val thumbWidthField = "thumb_width"
const val thumbHeightField = "thumb_height"

View File

@@ -7,6 +7,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.ParseMode
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.parseModeField
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -18,6 +19,8 @@ data class InlineQueryResultGifImpl(
override val url: String,
@SerialName(thumbUrlField)
override val thumbUrl: String,
@SerialName(thumbMimeTypeField)
override val thumbMimeType: MimeType? = null,
@SerialName(gifWidthField)
override val width: Int? = null,
@SerialName(gifHeightField)
@@ -36,4 +39,10 @@ data class InlineQueryResultGifImpl(
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultGif {
override val type: String = inlineQueryResultGifType
init {
if (thumbMimeType != null && thumbMimeType !in telegramInlineModeGifPermittedMimeTypes) {
error("Passed thumb mime type is not permitted in Telegram Bot API. Passed $thumbMimeType, but permitted $telegramInlineModeGifPermittedMimeTypes")
}
}
}

View File

@@ -7,6 +7,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.ParseMode
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.parseModeField
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.utils.MimeType
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -18,6 +19,8 @@ data class InlineQueryResultMpeg4GifImpl(
override val url: String,
@SerialName(thumbUrlField)
override val thumbUrl: String,
@SerialName(thumbMimeTypeField)
override val thumbMimeType: MimeType? = null,
@SerialName(mpeg4GifWidthField)
override val width: Int? = null,
@SerialName(mpeg4GifHeightField)
@@ -36,4 +39,10 @@ data class InlineQueryResultMpeg4GifImpl(
override val inputMessageContent: InputMessageContent? = null
) : InlineQueryResultMpeg4Gif {
override val type: String = inlineQueryResultMpeg4GifType
init {
if (thumbMimeType != null && thumbMimeType !in telegramInlineModeGifPermittedMimeTypes) {
error("Passed thumb mime type is not permitted in Telegram Bot API. Passed $thumbMimeType, but permitted $telegramInlineModeGifPermittedMimeTypes")
}
}
}

View File

@@ -1,5 +1,11 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InlineQueryResult.abstracts
import com.github.insanusmokrassar.TelegramBotAPI.utils.MimeType
interface ThumbedInlineQueryResult : InlineQueryResult {
val thumbUrl: String?
}
interface ThumbedWithMimeTypeInlineQueryResult : ThumbedInlineQueryResult {
val thumbMimeType: MimeType?
}

View File

@@ -2,4 +2,4 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InlineQue
import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InlineQueryResult.abstracts.*
interface InlineQueryResultGif : InlineQueryResultGifCommon, UrlInlineQueryResult, ThumbedInlineQueryResult, SizedInlineQueryResult, DuratedInlineResultQuery
interface InlineQueryResultGif : InlineQueryResultGifCommon, UrlInlineQueryResult, ThumbedWithMimeTypeInlineQueryResult, SizedInlineQueryResult, DuratedInlineResultQuery

View File

@@ -2,4 +2,4 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InlineQue
import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InlineQueryResult.abstracts.*
interface InlineQueryResultMpeg4Gif : InlineQueryResultMpeg4GifCommon, UrlInlineQueryResult, ThumbedInlineQueryResult, SizedInlineQueryResult, DuratedInlineResultQuery
interface InlineQueryResultMpeg4Gif : InlineQueryResultMpeg4GifCommon, UrlInlineQueryResult, ThumbedWithMimeTypeInlineQueryResult, SizedInlineQueryResult, DuratedInlineResultQuery

View File

@@ -1,19 +1,6 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CommonVenueData
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
@Serializable
data class Venue(
@SerialName(locationField)
val location: Location,
@SerialName(titleField)
override val title: String,
@SerialName(addressField)
override val address: String,
@SerialName(foursquareIdField)
override val foursquareId: String? = null,
@SerialName(foursquareTypeField)
override val foursquareType: String? = null
) : CommonVenueData
@Deprecated("Replaced", ReplaceWith("Venue", "com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue"))
typealias Venue = Venue

View File

@@ -1,12 +1,11 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.message
import com.github.insanusmokrassar.TelegramBotAPI.types.AuthorSignature
import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.Chat
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.PossiblySentViaBotCommonMessage
import com.soywiz.klock.DateTime
data class ChannelMessage<T: MessageContent>(
@@ -18,5 +17,6 @@ data class ChannelMessage<T: MessageContent>(
override val forwardInfo: ForwardInfo?,
override val replyTo: Message?,
override val replyMarkup: InlineKeyboardMarkup?,
override val senderBot: CommonBot?,
val authorSignature: AuthorSignature?
) : CommonMessage<T>
) : PossiblySentViaBotCommonMessage<T>

View File

@@ -1,11 +1,12 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.message
import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.User
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.Chat
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.FromUserMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.PossiblySentViaBotCommonMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.payments.SuccessfulPaymentInfo
import com.soywiz.klock.DateTime
@@ -19,5 +20,6 @@ data class CommonMessageImpl<T: MessageContent>(
override val forwardInfo: ForwardInfo?,
override val replyTo: Message?,
override val replyMarkup: InlineKeyboardMarkup?,
override val senderBot: CommonBot?,
val paymentInfo: SuccessfulPaymentInfo?
) : Message, CommonMessage<T>, FromUserMessage
) : PossiblySentViaBotCommonMessage<T>, FromUserMessage

View File

@@ -20,6 +20,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.payments.Success
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.Invoice
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.SuccessfulPayment
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.reflect.KClass
@@ -42,6 +43,7 @@ internal data class RawMessage(
private val forward_sender_name: ForwardSenderName? = null,
private val forward_date: TelegramDate? = null,
private val reply_to_message: RawMessage? = null,
private val via_bot: CommonBot? = null,
private val edit_date: TelegramDate? = null,
private val media_group_id: MediaGroupIdentifier? = null,
private val author_signature: AuthorSignature? = null,
@@ -147,7 +149,7 @@ internal data class RawMessage(
)
forward_from_chat is ChannelChat -> ForwardFromChannelInfo(
forward_date,
forward_from_message_id ?: throw IllegalStateException("Channel forwarded message must contain message id, but was not"),
forward_from_message_id ?: error("Channel forwarded message must contain message id, but was not"),
forward_from_chat,
forward_signature
)
@@ -208,7 +210,7 @@ internal data class RawMessage(
chatEvent as? ChannelEvent ?: throwWrongChatEvent(ChannelEvent::class, chatEvent),
date.asDate
)
else -> throw IllegalStateException("Expected one of the public chats, but was $chat (in extracting of chat event message)")
else -> error("Expected one of the public chats, but was $chat (in extracting of chat event message)")
}
} ?: content?.let { content ->
media_group_id?.let {
@@ -221,7 +223,7 @@ internal data class RawMessage(
when (content) {
is PhotoContent -> content
is VideoContent -> content
else -> throw IllegalStateException("Unsupported content for media group")
else -> error("Unsupported content for media group")
},
edit_date?.asDate,
forwarded,
@@ -237,7 +239,7 @@ internal data class RawMessage(
when (content) {
is PhotoContent -> content
is VideoContent -> content
else -> throw IllegalStateException("Unsupported content for media group")
else -> error("Unsupported content for media group")
},
edit_date?.asDate,
forwarded,
@@ -255,12 +257,12 @@ internal data class RawMessage(
forwarded,
reply_to_message?.asMessage,
reply_markup,
via_bot,
author_signature
)
else -> CommonMessageImpl(
messageId,
from
?: throw IllegalStateException("Was detected common message, but owner (sender) of the message was not found"),
from ?: error("Was detected common message, but owner (sender) of the message was not found"),
chat,
content,
date.asDate,
@@ -268,10 +270,11 @@ internal data class RawMessage(
forwarded,
reply_to_message?.asMessage,
reply_markup,
via_bot,
paymentInfo
)
}
} ?: throw IllegalStateException("Was not found supported type of data")
} ?: error("Was not found supported type of data")
} catch (e: Exception) {
UnknownMessageType(
messageId,
@@ -283,6 +286,6 @@ internal data class RawMessage(
}
private fun throwWrongChatEvent(expected: KClass<*>, but: ChatEvent): CommonEvent {
throw IllegalStateException("Wrong type of chat event: expected $expected, but was $but")
error("Wrong type of chat event: expected $expected, but was $but")
}
}

View File

@@ -0,0 +1,7 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts
import com.github.insanusmokrassar.TelegramBotAPI.types.CommonBot
interface PossiblySentViaBot {
val senderBot: CommonBot?
}

View File

@@ -2,10 +2,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.requests.send.SendVenue
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.ContentMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
import com.github.insanusmokrassar.TelegramBotAPI.types.venue.Venue
data class VenueContent(
val venue: Venue

View File

@@ -0,0 +1,6 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.CommonMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.PossiblySentViaBot
interface PossiblySentViaBotCommonMessage<T: MessageContent> : CommonMessage<T>, PossiblySentViaBot

View File

@@ -9,7 +9,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.payments.PreCheckoutQuer
import com.github.insanusmokrassar.TelegramBotAPI.types.payments.ShippingQuery
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.Poll
import com.github.insanusmokrassar.TelegramBotAPI.types.polls.PollAnswer
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdateType
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import com.github.insanusmokrassar.TelegramBotAPI.types.updateIdField
import kotlinx.serialization.*
@@ -57,7 +57,7 @@ internal data class RawUpdate constructor(
pre_checkout_query != null -> PreCheckoutQueryUpdate(updateId, pre_checkout_query)
poll != null -> PollUpdate(updateId, poll)
poll_answer != null -> PollAnswerUpdate(updateId, poll_answer)
else -> UnknownUpdateType(
else -> UnknownUpdate(
updateId,
raw.toString(),
raw
@@ -66,7 +66,7 @@ internal data class RawUpdate constructor(
} catch (e: Error) {
when (e) {
is SerializationException,
is NotImplementedError -> UnknownUpdateType(
is NotImplementedError -> UnknownUpdate(
updateId,
raw.toString(),
raw

View File

@@ -12,11 +12,13 @@ interface Update {
val data: Any
}
data class UnknownUpdateType(
data class UnknownUpdate(
override val updateId: UpdateIdentifier,
override val data: String,
val rawJson: JsonElement
) : Update
@Deprecated("Renamed", ReplaceWith("UnknownUpdate"))
typealias UnknownUpdateType = UnknownUpdate
internal object UpdateSerializerWithoutSerialization : KSerializer<Update> {
override val descriptor: SerialDescriptor = JsonElementSerializer.descriptor

View File

@@ -0,0 +1,21 @@
package com.github.insanusmokrassar.TelegramBotAPI.types.venue
import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CommonVenueData
import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.Locationed
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Venue(
@SerialName(locationField)
val location: Location,
@SerialName(titleField)
override val title: String,
@SerialName(addressField)
override val address: String,
@SerialName(foursquareIdField)
override val foursquareId: FoursquareId? = null,
@SerialName(foursquareTypeField)
override val foursquareType: FoursquareType? = null
) : CommonVenueData, Locationed by location

View File

@@ -1,74 +1,41 @@
package com.github.insanusmokrassar.TelegramBotAPI.updateshandlers
import com.github.insanusmokrassar.TelegramBotAPI.types.ALL_UPDATES_LIST
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
@Suppress("EXPERIMENTAL_API_USAGE")
private fun <T> BroadcastChannel<T>.createUpdateReceiver(): UpdateReceiver<T> = ::send
import kotlinx.coroutines.flow.*
@Suppress("EXPERIMENTAL_API_USAGE", "unused")
class FlowsUpdatesFilter(
broadcastChannelsSize: Int = 64
broadcastChannelsSize: Int = 100
): UpdatesFilter {
private val messageChannel: BroadcastChannel<MessageUpdate> = BroadcastChannel(broadcastChannelsSize)
private val messageMediaGroupChannel: BroadcastChannel<MessageMediaGroupUpdate> = BroadcastChannel(broadcastChannelsSize)
private val editedMessageChannel: BroadcastChannel<EditMessageUpdate> = BroadcastChannel(broadcastChannelsSize)
private val editedMessageMediaGroupChannel: BroadcastChannel<EditMessageMediaGroupUpdate> = BroadcastChannel(broadcastChannelsSize)
private val channelPostChannel: BroadcastChannel<ChannelPostUpdate> = BroadcastChannel(broadcastChannelsSize)
private val channelPostMediaGroupChannel: BroadcastChannel<ChannelPostMediaGroupUpdate> = BroadcastChannel(broadcastChannelsSize)
private val editedChannelPostChannel: BroadcastChannel<EditChannelPostUpdate> = BroadcastChannel(broadcastChannelsSize)
private val editedChannelPostMediaGroupChannel: BroadcastChannel<EditChannelPostMediaGroupUpdate> = BroadcastChannel(broadcastChannelsSize)
private val chosenInlineResultChannel: BroadcastChannel<ChosenInlineResultUpdate> = BroadcastChannel(broadcastChannelsSize)
private val inlineQueryChannel: BroadcastChannel<InlineQueryUpdate> = BroadcastChannel(broadcastChannelsSize)
private val callbackQueryChannel: BroadcastChannel<CallbackQueryUpdate> = BroadcastChannel(broadcastChannelsSize)
private val shippingQueryChannel: BroadcastChannel<ShippingQueryUpdate> = BroadcastChannel(broadcastChannelsSize)
private val preCheckoutQueryChannel: BroadcastChannel<PreCheckoutQueryUpdate> = BroadcastChannel(broadcastChannelsSize)
private val pollChannel: BroadcastChannel<PollUpdate> = BroadcastChannel(broadcastChannelsSize)
private val pollAnswerChannel: BroadcastChannel<PollAnswerUpdate> = BroadcastChannel(broadcastChannelsSize)
private val unknownUpdateChannel: BroadcastChannel<Update> = BroadcastChannel(broadcastChannelsSize)
private val updatesReceivingChannel = BroadcastChannel<Update>(broadcastChannelsSize)
@Suppress("MemberVisibilityCanBePrivate")
val allUpdatesFlow: Flow<Update> = updatesReceivingChannel.asFlow()
override val allowedUpdates: List<String>
get() = filter.allowedUpdates
override val asUpdateReceiver: UpdateReceiver<Update>
get() = filter.asUpdateReceiver
val filter = SimpleUpdatesFilter(
messageChannel.createUpdateReceiver(),
messageMediaGroupChannel.createUpdateReceiver(),
editedMessageChannel.createUpdateReceiver(),
editedMessageMediaGroupChannel.createUpdateReceiver(),
channelPostChannel.createUpdateReceiver(),
channelPostMediaGroupChannel.createUpdateReceiver(),
editedChannelPostChannel.createUpdateReceiver(),
editedChannelPostMediaGroupChannel.createUpdateReceiver(),
chosenInlineResultChannel.createUpdateReceiver(),
inlineQueryChannel.createUpdateReceiver(),
callbackQueryChannel.createUpdateReceiver(),
shippingQueryChannel.createUpdateReceiver(),
preCheckoutQueryChannel.createUpdateReceiver(),
pollChannel.createUpdateReceiver(),
pollAnswerChannel.createUpdateReceiver(),
unknownUpdateChannel.createUpdateReceiver()
)
val messageFlow: Flow<MessageUpdate> = messageChannel.asFlow()
val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate> = messageMediaGroupChannel.asFlow()
val editedMessageFlow: Flow<EditMessageUpdate> = editedMessageChannel.asFlow()
val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate> = editedMessageMediaGroupChannel.asFlow()
val channelPostFlow: Flow<ChannelPostUpdate> = channelPostChannel.asFlow()
val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate> = channelPostMediaGroupChannel.asFlow()
val editedChannelPostFlow: Flow<EditChannelPostUpdate> = editedChannelPostChannel.asFlow()
val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate> = editedChannelPostMediaGroupChannel.asFlow()
val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate> = chosenInlineResultChannel.asFlow()
val inlineQueryFlow: Flow<InlineQueryUpdate> = inlineQueryChannel.asFlow()
val callbackQueryFlow: Flow<CallbackQueryUpdate> = callbackQueryChannel.asFlow()
val shippingQueryFlow: Flow<ShippingQueryUpdate> = shippingQueryChannel.asFlow()
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = preCheckoutQueryChannel.asFlow()
val pollFlow: Flow<PollUpdate> = pollChannel.asFlow()
val pollAnswerFlow: Flow<PollAnswerUpdate> = pollAnswerChannel.asFlow()
val unknownUpdateTypeFlow: Flow<Update> = unknownUpdateChannel.asFlow()
get() = ALL_UPDATES_LIST
override val asUpdateReceiver: UpdateReceiver<Update> = {
updatesReceivingChannel.send(it)
}
val messageFlow: Flow<MessageUpdate> = allUpdatesFlow.filterIsInstance()
val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
val editedMessageFlow: Flow<EditMessageUpdate> = allUpdatesFlow.filterIsInstance()
val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
val channelPostFlow: Flow<ChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
val editedChannelPostFlow: Flow<EditChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate> = allUpdatesFlow.filterIsInstance()
val inlineQueryFlow: Flow<InlineQueryUpdate> = allUpdatesFlow.filterIsInstance()
val callbackQueryFlow: Flow<CallbackQueryUpdate> = allUpdatesFlow.filterIsInstance()
val shippingQueryFlow: Flow<ShippingQueryUpdate> = allUpdatesFlow.filterIsInstance()
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
val pollFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
val pollAnswerFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
val unknownUpdateTypeFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
}

View File

@@ -3,7 +3,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.updateshandlers
import com.github.insanusmokrassar.TelegramBotAPI.types.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.MediaGroupUpdates.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdateType
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.UnknownUpdate
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.Update
typealias UpdateReceiver<T> = suspend (T) -> Unit
@@ -29,7 +29,7 @@ data class SimpleUpdatesFilter(
private val preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
private val pollUpdateCallback: UpdateReceiver<PollUpdate>? = null,
private val pollAnswerUpdateCallback: UpdateReceiver<PollAnswerUpdate>? = null,
private val unknownUpdateTypeCallback: UpdateReceiver<UnknownUpdateType>? = null
private val unknownUpdateTypeCallback: UpdateReceiver<UnknownUpdate>? = null
) : UpdatesFilter {
override val asUpdateReceiver: UpdateReceiver<Update> = this::invoke
override val allowedUpdates = listOfNotNull(
@@ -83,7 +83,7 @@ data class SimpleUpdatesFilter(
is PreCheckoutQueryUpdate -> preCheckoutQueryCallback ?.invoke(update)
is PollUpdate -> pollUpdateCallback ?.invoke(update)
is PollAnswerUpdate -> pollAnswerUpdateCallback ?.invoke(update)
is UnknownUpdateType -> unknownUpdateTypeCallback ?.invoke(update)
is UnknownUpdate -> unknownUpdateTypeCallback ?.invoke(update)
}
}
}
@@ -101,7 +101,7 @@ fun createSimpleUpdateFilter(
preCheckoutQueryCallback: UpdateReceiver<PreCheckoutQueryUpdate>? = null,
pollCallback: UpdateReceiver<PollUpdate>? = null,
pollAnswerCallback: UpdateReceiver<PollAnswerUpdate>? = null,
unknownCallback: UpdateReceiver<UnknownUpdateType>? = null
unknownCallback: UpdateReceiver<UnknownUpdate>? = null
): UpdatesFilter = SimpleUpdatesFilter(
messageCallback = messageCallback,
messageMediaGroupCallback = mediaGroupCallback,

View File

@@ -1,7 +1,7 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
@RequiresOptIn(
"It is possible, that behaviour of this thing will be changed later",
"It is possible, that behaviour of this thing will be changed later or this feature will be removed",
RequiresOptIn.Level.WARNING
)
@Target(

View File

@@ -0,0 +1,11 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
object BuiltinMimeTypes {
object Image {
val Jpg = buildMimeType("image/jpeg")
val Gif = buildMimeType("image/gif")
}
object Video {
val MP4 = buildMimeType("video/mp4")
}
}

View File

@@ -6,9 +6,10 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.fullEntitiesList
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun createFormattedText(
entities: FullTextSourcesList,
partLength: Int = 4096,
partLength: Int = textLength.last,
mode: ParseMode = MarkdownParseMode
): List<String> {
val texts = mutableListOf<String>()
@@ -47,75 +48,96 @@ fun createFormattedText(
}
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun createMarkdownText(
entities: FullTextSourcesList,
partLength: Int = 4096
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownCaptions(): List<String> = createMarkdownText(
this,
captionLength.last + 1
captionLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun CaptionedInput.toMarkdownCaptions(): List<String> = fullEntitiesList().toMarkdownCaptions()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownTexts(): List<String> = createMarkdownText(
this,
textLength.last + 1
textLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun TextContent.toMarkdownTexts(): List<String> = fullEntitiesList().toMarkdownTexts()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownExplanations(): List<String> = createMarkdownText(
this,
explanationLimit.last + 1
explanationLimit.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun ExplainedInput.toMarkdownExplanations(): List<String> = fullEntitiesList().toMarkdownTexts()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun createMarkdownV2Text(
entities: FullTextSourcesList,
partLength: Int = 4096
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
this,
captionLength.last + 1
captionLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun CaptionedInput.toMarkdownV2Captions(): List<String> = fullEntitiesList().toMarkdownV2Captions()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownV2Texts(): List<String> = createMarkdownV2Text(
this,
textLength.last + 1
textLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun TextContent.toMarkdownV2Texts(): List<String> = fullEntitiesList().toMarkdownV2Texts()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toMarkdownV2Explanations(): List<String> = createMarkdownV2Text(
this,
explanationLimit.last + 1
explanationLimit.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun ExplainedInput.toMarkdownV2Explanations(): List<String> = fullEntitiesList().toMarkdownV2Texts()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun createHtmlText(
entities: FullTextSourcesList,
partLength: Int = 4096
partLength: Int = textLength.last
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
this,
captionLength.last + 1
captionLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun CaptionedInput.toHtmlCaptions(): List<String> = fullEntitiesList().toHtmlCaptions()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toHtmlTexts(): List<String> = createHtmlText(
this,
textLength.last + 1
textLength.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun TextContent.toHtmlTexts(): List<String> = fullEntitiesList().toHtmlTexts()
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun FullTextSourcesList.toHtmlExplanations(): List<String> = createHtmlText(
this,
explanationLimit.last + 1
explanationLimit.last
)
@Deprecated("Replaced into TelegramBotAPI-extensions-utils")
fun ExplainedInput.toHtmlExplanations(): List<String> = fullEntitiesList().toHtmlTexts()

View File

@@ -7,6 +7,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.extended.
private const val internalLinkBeginning = "https://t.me"
@Deprecated("Replaced into TelegramBotAPI-extensions-utils project")
fun makeLinkToMessage(
username: String,
messageId: MessageIdentifier
@@ -15,6 +16,7 @@ fun makeLinkToMessage(
private val linkIdRedundantPartRegex = Regex("^-100")
private val usernameBeginSymbolRegex = Regex("^@")
@Deprecated("Replaced into TelegramBotAPI-extensions-utils project")
fun makeLinkToMessage(
chat: ExtendedChat,
messageId: MessageIdentifier

View File

@@ -10,16 +10,35 @@ fun <T> MatrixBuilder<T>.row(block: RowBuilder<T>.() -> Unit) {
add(RowBuilder<T>().also(block).row)
}
fun <T> MatrixBuilder<T>.row(vararg elements: T) {
add(elements.toList())
}
fun <T> matrix(block: MatrixBuilder<T>.() -> Unit): Matrix<T> {
return MatrixBuilder<T>().also(block).matrix
}
fun <T> flatMatrix(block: RowBuilder<T>.() -> Unit): Matrix<T> {
return MatrixBuilder<T>().apply {
row(block)
}.matrix
}
fun <T> flatMatrix(vararg elements: T): Matrix<T> {
return MatrixBuilder<T>().apply {
row { elements.forEach { +it } }
}.matrix
}
operator fun <T> RowBuilder<T>.plus(t: T) = add(t)
class RowBuilder<T> {
private val mutRow: MutableList<T> = ArrayList()
val row: List<T>
get() = mutRow
fun add(t: T) = mutRow.add(t)
operator fun T.unaryPlus() = add(this)
}
class MatrixBuilder<T> {

View File

@@ -6,18 +6,22 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.message.ForwardInfo
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.types.update.abstracts.BaseMessageUpdate
@Deprecated("Replaced and updated inside of TelegramBotAPI-extensions-utils")
val List<BaseMessageUpdate>.forwarded: ForwardInfo?
get() = first().let {
(it as? PossiblyForwardedMessage) ?.forwardInfo
}
@Deprecated("Replaced and updated inside of TelegramBotAPI-extensions-utils")
val List<BaseMessageUpdate>.replyTo: Message?
get() = first().let {
(it as? PossiblyReplyMessage) ?.replyTo
}
@Deprecated("Replaced and updated inside of TelegramBotAPI-extensions-utils")
val List<BaseMessageUpdate>.chat: Chat?
get() = first().data.chat
@Deprecated("Replaced and updated inside of TelegramBotAPI-extensions-utils")
val List<BaseMessageUpdate>.mediaGroupId: MediaGroupIdentifier?
get() = (first().data as? MediaGroupMessage) ?.mediaGroupId

View File

@@ -7,5 +7,7 @@ expect class MimeType {
val raw: String
}
expect fun buildMimeType(raw: String): MimeType
@Serializer(MimeType::class)
internal expect object MimeTypeSerializer : KSerializer<MimeType>

View File

@@ -36,50 +36,71 @@ private fun String.htmlDefault(
closeControlSymbol: String = openControlSymbol
) = "<$openControlSymbol>${toHtml()}</$closeControlSymbol>"
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.linkMarkdown(link: String): String = "[${toMarkdown()}](${link.toMarkdown()})"
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.linkMarkdownV2(link: String): String = "[${escapeMarkdownV2Common()}](${link.escapeMarkdownV2Link()})"
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.linkHTML(link: String): String = "<a href=\"$link\">${toHtml()}</a>"
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.boldMarkdown(): String = markdownDefault(markdownBoldControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.boldHTML(): String = htmlDefault(htmlBoldControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.italicMarkdown(): String = markdownDefault(markdownItalicControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl, markdownV2ItalicEndControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.italicHTML(): String = htmlDefault(htmlItalicControl)
/**
* Crutch for support of strikethrough in default markdown. Simply add modifier, but it will not look like correct
*/
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.strikethroughMarkdown(): String = map { it + "\u0336" }.joinToString("")
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl)
/**
* Crutch for support of underline in default markdown. Simply add modifier, but it will not look like correct
*/
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.underlineMarkdown(): String = map { it + "\u0347" }.joinToString("")
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl, markdownV2UnderlineEndControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.underlineHTML(): String = htmlDefault(htmlUnderlineControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.codeMarkdown(): String = markdownDefault(markdownCodeControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.codeMarkdownV2(): String = markdownV2Default(markdownCodeControl, escapeFun = String::escapeMarkdownV2PreAndCode)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.codeHTML(): String = htmlDefault(htmlCodeControl)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.preMarkdown(language: String? = null): String = markdownDefault(
"$markdownPreControl${language ?: ""}\n",
"\n$markdownPreControl"
)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.preMarkdownV2(language: String? = null): String = markdownV2Default(
"$markdownPreControl${language ?: ""}\n",
"\n$markdownPreControl",
String::escapeMarkdownV2PreAndCode
)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.preHTML(language: String? = null): String = htmlDefault(
language ?.let {
"$htmlPreControl><$htmlCodeControl class=\"language-$language\""
@@ -90,11 +111,15 @@ fun String.preHTML(language: String? = null): String = htmlDefault(
)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.emailMarkdown(): String = linkMarkdown("mailto://$${toMarkdown()}")
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.emailMarkdownV2(): String = linkMarkdownV2("mailto://$${toMarkdown()}")
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.emailHTML(): String = linkHTML("mailto://$${toHtml()}")
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
private inline fun String.mention(adapt: String.() -> String): String = if (startsWith("@")) {
adapt()
} else {
@@ -102,6 +127,7 @@ private inline fun String.mention(adapt: String.() -> String): String = if (star
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
private inline fun String.hashTag(adapt: String.() -> String): String = if (startsWith("#")) {
adapt()
} else {
@@ -109,47 +135,70 @@ private inline fun String.hashTag(adapt: String.() -> String): String = if (star
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.textMentionMarkdown(userId: UserId): String = linkMarkdown(userId.link)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.textMentionHTML(userId: UserId): String = linkHTML(userId.link)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.mentionMarkdown(): String = mention(String::toMarkdown)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.mentionMarkdownV2(): String = mention(String::escapeMarkdownV2Common)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.mentionHTML(): String = mention(String::toHtml)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.hashTagMarkdown(): String = hashTag(String::toMarkdown)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.hashTagMarkdownV2(): String = hashTag(String::escapeMarkdownV2Common).escapeMarkdownV2Common()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.hashTagHTML(): String = hashTag(String::toHtml)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.phoneMarkdown(): String = toMarkdown()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.phoneMarkdownV2(): String = escapeMarkdownV2Common()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.phoneHTML(): String = toHtml()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.command(adapt: String.() -> String): String = if (startsWith("/")) {
adapt()
} else {
"/${adapt()}"
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.commandMarkdown(): String = command(String::toMarkdown)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.commandMarkdownV2(): String = command(String::escapeMarkdownV2Common)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.commandHTML(): String = command(String::toHtml)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.regularMarkdown(): String = toMarkdown()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.regularMarkdownV2(): String = escapeMarkdownV2Common()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.regularHtml(): String = toHtml()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.cashTagMarkdown(): String = toMarkdown()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.cashTagMarkdownV2(): String = escapeMarkdownV2Common()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.cashTagHtml(): String = toHtml()
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.bold(parseMode: ParseMode): String = when (parseMode) {
is HTML -> boldHTML()
is Markdown -> boldMarkdown()
@@ -157,85 +206,100 @@ infix fun String.bold(parseMode: ParseMode): String = when (parseMode) {
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.italic(parseMode: ParseMode): String = when (parseMode) {
is HTML -> italicHTML()
is Markdown -> italicMarkdown()
is MarkdownV2 -> italicMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.hashTag(parseMode: ParseMode): String = when (parseMode) {
is HTML -> hashTagHTML()
is Markdown -> hashTagMarkdown()
is MarkdownV2 -> hashTagMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.code(parseMode: ParseMode): String = when (parseMode) {
is HTML -> codeHTML()
is Markdown -> codeMarkdown()
is MarkdownV2 -> codeMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
fun String.pre(parseMode: ParseMode, language: String? = null): String = when (parseMode) {
is HTML -> preHTML(language)
is Markdown -> preMarkdown(language)
is MarkdownV2 -> preMarkdownV2(language)
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.pre(parseMode: ParseMode): String = pre(parseMode, null)
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.email(parseMode: ParseMode): String = when (parseMode) {
is HTML -> emailHTML()
is Markdown -> emailMarkdown()
is MarkdownV2 -> emailMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun Pair<String, String>.link(parseMode: ParseMode): String = when (parseMode) {
is HTML -> first.linkHTML(second)
is Markdown -> first.linkMarkdown(second)
is MarkdownV2 -> first.linkMarkdownV2(second)
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.mention(parseMode: ParseMode): String = when (parseMode) {
is HTML -> mentionHTML()
is Markdown -> mentionMarkdown()
is MarkdownV2 -> mentionMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun Pair<String, ChatId>.mention(parseMode: ParseMode): String = when (parseMode) {
is HTML -> first.textMentionHTML(second)
is Markdown -> first.textMentionMarkdown(second)
is MarkdownV2 -> first.textMentionMarkdownV2(second)
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.phone(parseMode: ParseMode): String = when (parseMode) {
is HTML -> phoneHTML()
is Markdown -> phoneMarkdown()
is MarkdownV2 -> phoneMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.command(parseMode: ParseMode): String = when (parseMode) {
is HTML -> commandHTML()
is Markdown -> commandMarkdown()
is MarkdownV2 -> commandMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.underline(parseMode: ParseMode): String = when (parseMode) {
is HTML -> underlineHTML()
is Markdown -> underlineMarkdown()
is MarkdownV2 -> underlineMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.strikethrough(parseMode: ParseMode): String = when (parseMode) {
is HTML -> strikethroughHTML()
is Markdown -> strikethroughMarkdown()
is MarkdownV2 -> strikethroughMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.regular(parseMode: ParseMode): String = when (parseMode) {
is HTML -> regularHtml()
is Markdown -> regularMarkdown()
is MarkdownV2 -> regularMarkdownV2()
}
@Deprecated("Replaced into project TelegramBotAPI-extensions-utils")
infix fun String.cashtag(parseMode: ParseMode): String = when (parseMode) {
is HTML -> cashTagHtml()
is Markdown -> cashTagMarkdown()

View File

@@ -0,0 +1,7 @@
package com.github.insanusmokrassar.TelegramBotAPI.utils
internal fun throwRangeError(
valueName: String,
range: IntRange,
actualValue: Int
): Nothing = error("$valueName must be in range $range, but was $actualValue")

View File

@@ -7,7 +7,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import com.github.insanusmokrassar.TelegramBotAPI.utils.handleSafely
import kotlinx.coroutines.*
@Deprecated("Will be removed in next major update")
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
onFail: (suspend (Response) -> Unit)? = null,
@@ -24,6 +24,7 @@ fun <T: Any> RequestsExecutor.executeAsync(
}
}
@Deprecated("Replaced and modified inside of TelegramBotAPI-extensions-utils")
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
scope: CoroutineScope = GlobalScope
@@ -31,6 +32,7 @@ fun <T: Any> RequestsExecutor.executeAsync(
return scope.async { execute(request) }
}
@Deprecated("Replaced and modified inside of TelegramBotAPI-extensions-utils")
suspend fun <T: Any> RequestsExecutor.executeUnsafe(
request: Request<T>,
retries: Int = 0,

View File

@@ -23,7 +23,7 @@ internal actual object MimeTypeSerializer : KSerializer<MimeType> {
override fun deserialize(decoder: Decoder): MimeType {
val mimeType = decoder.decodeString()
return mimesCache.getOrPut(mimeType) {
MimeType(mimeType)
buildMimeType(mimeType)
}
}
@@ -31,3 +31,5 @@ internal actual object MimeTypeSerializer : KSerializer<MimeType> {
encoder.encodeString(value.raw)
}
}
actual fun buildMimeType(raw: String) = MimeType(raw)

View File

@@ -24,3 +24,5 @@ internal actual object MimeTypeSerializer : KSerializer<MimeType> {
encoder.encodeString(value.raw)
}
}
actual fun buildMimeType(raw: String): MimeType = MimeType(raw)

View File

@@ -12,9 +12,9 @@
<path fill="url(#b)" d="M0 0h104v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
<text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">Talk</text>
<text x="175" y="140" transform="scale(.1)" textLength="250">Talk</text>
<text x="690" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="600">Telegram</text>
<text x="690" y="140" transform="scale(.1)" textLength="600">Telegram</text>
<text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Talk</text>
<text x="175" y="140" transform="scale(.1)">Talk</text>
<text x="690" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Telegram</text>
<text x="690" y="140" transform="scale(.1)">Telegram</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1018 B

20
badges/kdocs.svg Normal file
View File

@@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="104" height="20">
<linearGradient id="b" x2="0" y2="100%">
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
<stop offset="1" stop-opacity=".1"/>
</linearGradient>
<clipPath id="a">
<rect width="104" height="20" rx="3" fill="#fff"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#555" d="M0 0h65v20H0z"/>
<path fill="#007ec6" d="M45 0h69v20H45z"/>
<path fill="url(#b)" d="M0 0h104v20H0z"/>
</g>
<g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
<text x="225" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">Open</text>
<text x="225" y="140" transform="scale(.1)">Open</text>
<text x="740" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">KDocs</text>
<text x="740" y="140" transform="scale(.1)">KDocs</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1012 B

View File

@@ -63,11 +63,17 @@ private Closure includeSourcesInDokka(String... approximateNames) {
}
}
String dokkaFolder = "$buildDir/dokka"
dokka {
outputFormat = 'html'
outputDirectory = dokkaFolder
switch (true) {
case project.hasProperty("DOKKA_PATH"):
outputDirectory = project.property("DOKKA_PATH").toString()
break
case System.getenv("DOKKA_PATH") != null:
outputDirectory = System.getenv("DOKKA_PATH")
break
}
multiplatform {
global {

View File

@@ -1,14 +1,14 @@
kotlin.code.style=official
kotlin_version=1.3.72
kotlin_coroutines_version=1.3.6
kotlin_coroutines_version=1.3.7
kotlin_serialisation_runtime_version=0.20.0
klock_version=1.11.1
klock_version=1.11.3
uuid_version=0.1.0
ktor_version=1.3.2
javax_activation_version=1.1.1
library_group=com.github.insanusmokrassar
library_version=0.27.4
library_version=0.27.8
gradle_bintray_plugin_version=1.8.4

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

View File

@@ -0,0 +1,851 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="744pt" height="1051pt" viewBox="0 0 744 1051" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 10.546875 -11.5625 L 6.4375 -11.5625 L 6.4375 0 L 4.796875 0 L 4.796875 -11.5625 L 0.6875 -11.5625 L 0.6875 -13 L 10.546875 -13 Z M 10.546875 -11.5625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 5.9375 0 C 5.25 0 4.613281 -0.113281 4.03125 -0.34375 C 3.445312 -0.582031 2.945312 -0.910156 2.53125 -1.328125 C 2.125 -1.742188 1.804688 -2.238281 1.578125 -2.8125 C 1.347656 -3.382812 1.234375 -4 1.234375 -4.65625 L 1.234375 -5.046875 C 1.234375 -5.828125 1.359375 -6.519531 1.609375 -7.125 C 1.867188 -7.738281 2.207031 -8.257812 2.625 -8.6875 C 3.050781 -9.113281 3.53125 -9.4375 4.0625 -9.65625 C 4.601562 -9.882812 5.15625 -10 5.71875 -10 C 6.4375 -10 7.0625 -9.882812 7.59375 -9.65625 C 8.125 -9.425781 8.566406 -9.101562 8.921875 -8.6875 C 9.273438 -8.28125 9.535156 -7.796875 9.703125 -7.234375 C 9.878906 -6.679688 9.96875 -6.082031 9.96875 -5.4375 L 9.96875 -4.71875 L 2.921875 -4.71875 C 2.929688 -4.257812 3.015625 -3.828125 3.171875 -3.421875 C 3.328125 -3.015625 3.539062 -2.660156 3.8125 -2.359375 C 4.082031 -2.054688 4.40625 -1.816406 4.78125 -1.640625 C 5.164062 -1.460938 5.582031 -1.375 6.03125 -1.375 C 6.632812 -1.375 7.171875 -1.5 7.640625 -1.75 C 8.109375 -2.007812 8.5 -2.34375 8.8125 -2.75 L 9.84375 -1.921875 C 9.675781 -1.671875 9.46875 -1.425781 9.21875 -1.1875 C 8.976562 -0.957031 8.695312 -0.753906 8.375 -0.578125 C 8.050781 -0.410156 7.6875 -0.269531 7.28125 -0.15625 C 6.875 -0.0507812 6.425781 0 5.9375 0 Z M 5.71875 -8.625 C 5.382812 -8.625 5.0625 -8.566406 4.75 -8.453125 C 4.445312 -8.335938 4.175781 -8.171875 3.9375 -7.953125 C 3.695312 -7.742188 3.492188 -7.484375 3.328125 -7.171875 C 3.160156 -6.859375 3.039062 -6.5 2.96875 -6.09375 L 8.28125 -6.09375 L 8.28125 -6.203125 C 8.257812 -6.492188 8.195312 -6.785156 8.09375 -7.078125 C 7.988281 -7.367188 7.832031 -7.628906 7.625 -7.859375 C 7.414062 -8.085938 7.15625 -8.269531 6.84375 -8.40625 C 6.53125 -8.550781 6.15625 -8.625 5.71875 -8.625 Z M 5.71875 -8.625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 1.84375 -14 L 6.890625 -14 L 6.890625 -1.453125 L 10.109375 -1.453125 L 10.109375 0 L 1.84375 0 L 1.84375 -1.453125 L 5.203125 -1.453125 L 5.203125 -12.546875 L 1.84375 -12.546875 Z M 1.84375 -14 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 1.28125 -5.078125 C 1.28125 -5.804688 1.367188 -6.46875 1.546875 -7.0625 C 1.722656 -7.664062 1.976562 -8.179688 2.3125 -8.609375 C 2.65625 -9.046875 3.070312 -9.382812 3.5625 -9.625 C 4.050781 -9.875 4.601562 -10 5.21875 -10 C 5.820312 -10 6.351562 -9.890625 6.8125 -9.671875 C 7.269531 -9.460938 7.660156 -9.15625 7.984375 -8.75 L 8.0625 -10 L 9.59375 -10 L 9.59375 -0.15625 C 9.59375 0.5 9.488281 1.082031 9.28125 1.59375 C 9.082031 2.113281 8.800781 2.550781 8.4375 2.90625 C 8.070312 3.269531 7.632812 3.539062 7.125 3.71875 C 6.613281 3.90625 6.046875 4 5.421875 4 C 5.171875 4 4.878906 3.96875 4.546875 3.90625 C 4.222656 3.851562 3.890625 3.757812 3.546875 3.625 C 3.210938 3.488281 2.890625 3.3125 2.578125 3.09375 C 2.265625 2.875 1.992188 2.597656 1.765625 2.265625 L 2.640625 1.125 C 2.847656 1.40625 3.0625 1.640625 3.28125 1.828125 C 3.5 2.023438 3.71875 2.179688 3.9375 2.296875 C 4.164062 2.421875 4.390625 2.507812 4.609375 2.5625 C 4.835938 2.613281 5.066406 2.640625 5.296875 2.640625 C 5.703125 2.640625 6.0625 2.578125 6.375 2.453125 C 6.695312 2.328125 6.972656 2.140625 7.203125 1.890625 C 7.429688 1.648438 7.601562 1.351562 7.71875 1 C 7.84375 0.644531 7.90625 0.234375 7.90625 -0.234375 L 7.90625 -1.15625 C 7.582031 -0.78125 7.195312 -0.492188 6.75 -0.296875 C 6.300781 -0.0976562 5.785156 0 5.203125 0 C 4.597656 0 4.050781 -0.125 3.5625 -0.375 C 3.070312 -0.625 2.660156 -0.96875 2.328125 -1.40625 C 1.992188 -1.851562 1.734375 -2.375 1.546875 -2.96875 C 1.367188 -3.5625 1.28125 -4.203125 1.28125 -4.890625 Z M 2.96875 -4.890625 C 2.96875 -4.421875 3.015625 -3.976562 3.109375 -3.5625 C 3.210938 -3.144531 3.367188 -2.773438 3.578125 -2.453125 C 3.796875 -2.140625 4.070312 -1.890625 4.40625 -1.703125 C 4.75 -1.523438 5.148438 -1.4375 5.609375 -1.4375 C 5.898438 -1.4375 6.160156 -1.46875 6.390625 -1.53125 C 6.628906 -1.601562 6.84375 -1.695312 7.03125 -1.8125 C 7.21875 -1.9375 7.382812 -2.082031 7.53125 -2.25 C 7.675781 -2.425781 7.800781 -2.617188 7.90625 -2.828125 L 7.90625 -7.21875 C 7.800781 -7.414062 7.675781 -7.597656 7.53125 -7.765625 C 7.382812 -7.929688 7.21875 -8.070312 7.03125 -8.1875 C 6.84375 -8.300781 6.628906 -8.394531 6.390625 -8.46875 C 6.160156 -8.539062 5.910156 -8.578125 5.640625 -8.578125 C 5.160156 -8.578125 4.75 -8.484375 4.40625 -8.296875 C 4.070312 -8.109375 3.796875 -7.851562 3.578125 -7.53125 C 3.367188 -7.207031 3.210938 -6.832031 3.109375 -6.40625 C 3.015625 -5.988281 2.96875 -5.546875 2.96875 -5.078125 Z M 2.96875 -4.890625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 8.046875 -10 C 8.203125 -10 8.363281 -10 8.53125 -10 C 8.707031 -10 8.875 -9.988281 9.03125 -9.96875 C 9.1875 -9.945312 9.328125 -9.914062 9.453125 -9.875 C 9.585938 -9.84375 9.695312 -9.8125 9.78125 -9.78125 L 9.5625 -8.140625 C 9.226562 -8.210938 8.910156 -8.265625 8.609375 -8.296875 C 8.316406 -8.328125 8.007812 -8.34375 7.6875 -8.34375 C 6.90625 -8.34375 6.269531 -8.164062 5.78125 -7.8125 C 5.289062 -7.457031 4.929688 -6.957031 4.703125 -6.3125 L 4.703125 0 L 3 0 L 3 -10 L 4.609375 -10 L 4.6875 -8.265625 C 5.082031 -8.796875 5.5625 -9.21875 6.125 -9.53125 C 6.6875 -9.84375 7.328125 -10 8.046875 -10 Z M 8.046875 -10 "/>
</symbol>
<symbol overflow="visible" id="glyph0-6">
<path style="stroke:none;" d="M 8.0625 -0.1875 C 8 -0.3125 7.945312 -0.46875 7.90625 -0.65625 C 7.863281 -0.851562 7.835938 -1.054688 7.828125 -1.265625 C 7.648438 -1.085938 7.457031 -0.921875 7.25 -0.765625 C 7.039062 -0.617188 6.8125 -0.488281 6.5625 -0.375 C 6.3125 -0.257812 6.039062 -0.164062 5.75 -0.09375 C 5.46875 -0.03125 5.164062 0 4.84375 0 C 4.320312 0 3.847656 -0.0703125 3.421875 -0.21875 C 3.003906 -0.363281 2.644531 -0.5625 2.34375 -0.8125 C 2.050781 -1.070312 1.820312 -1.375 1.65625 -1.71875 C 1.5 -2.070312 1.421875 -2.445312 1.421875 -2.84375 C 1.421875 -3.375 1.523438 -3.835938 1.734375 -4.234375 C 1.953125 -4.628906 2.257812 -4.957031 2.65625 -5.21875 C 3.050781 -5.476562 3.523438 -5.671875 4.078125 -5.796875 C 4.640625 -5.929688 5.265625 -6 5.953125 -6 L 7.796875 -6 L 7.796875 -6.75 C 7.796875 -7.050781 7.738281 -7.316406 7.625 -7.546875 C 7.519531 -7.773438 7.363281 -7.96875 7.15625 -8.125 C 6.957031 -8.289062 6.710938 -8.414062 6.421875 -8.5 C 6.140625 -8.59375 5.820312 -8.640625 5.46875 -8.640625 C 5.125 -8.640625 4.820312 -8.597656 4.5625 -8.515625 C 4.300781 -8.429688 4.078125 -8.320312 3.890625 -8.1875 C 3.710938 -8.0625 3.570312 -7.90625 3.46875 -7.71875 C 3.363281 -7.53125 3.3125 -7.332031 3.3125 -7.125 L 1.625 -7.125 C 1.625 -7.476562 1.710938 -7.828125 1.890625 -8.171875 C 2.078125 -8.515625 2.335938 -8.816406 2.671875 -9.078125 C 3.015625 -9.347656 3.425781 -9.566406 3.90625 -9.734375 C 4.382812 -9.910156 4.929688 -10 5.546875 -10 C 6.109375 -10 6.628906 -9.929688 7.109375 -9.796875 C 7.585938 -9.660156 8 -9.457031 8.34375 -9.1875 C 8.695312 -8.925781 8.972656 -8.59375 9.171875 -8.1875 C 9.378906 -7.78125 9.484375 -7.304688 9.484375 -6.765625 L 9.484375 -2.296875 C 9.484375 -1.972656 9.515625 -1.628906 9.578125 -1.265625 C 9.640625 -0.910156 9.722656 -0.597656 9.828125 -0.328125 L 9.828125 -0.1875 Z M 5.09375 -1.46875 C 5.414062 -1.46875 5.71875 -1.503906 6 -1.578125 C 6.289062 -1.660156 6.550781 -1.769531 6.78125 -1.90625 C 7.019531 -2.039062 7.222656 -2.191406 7.390625 -2.359375 C 7.566406 -2.535156 7.703125 -2.71875 7.796875 -2.90625 L 7.796875 -4.8125 L 6.234375 -4.8125 C 5.242188 -4.8125 4.472656 -4.671875 3.921875 -4.390625 C 3.378906 -4.109375 3.109375 -3.671875 3.109375 -3.078125 C 3.109375 -2.847656 3.148438 -2.632812 3.234375 -2.4375 C 3.316406 -2.238281 3.4375 -2.066406 3.59375 -1.921875 C 3.757812 -1.773438 3.96875 -1.660156 4.21875 -1.578125 C 4.46875 -1.503906 4.757812 -1.46875 5.09375 -1.46875 Z M 5.09375 -1.46875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-7">
<path style="stroke:none;" d="M 2.359375 -10 L 2.40625 -8.90625 C 2.601562 -9.25 2.863281 -9.515625 3.1875 -9.703125 C 3.519531 -9.898438 3.914062 -10 4.375 -10 C 5.28125 -10 5.882812 -9.65625 6.1875 -8.96875 C 6.382812 -9.28125 6.640625 -9.53125 6.953125 -9.71875 C 7.273438 -9.90625 7.664062 -10 8.125 -10 C 8.84375 -10 9.394531 -9.773438 9.78125 -9.328125 C 10.175781 -8.890625 10.375 -8.222656 10.375 -7.328125 L 10.375 0 L 8.765625 0 L 8.765625 -7.359375 C 8.765625 -8.179688 8.382812 -8.59375 7.625 -8.59375 C 7.425781 -8.59375 7.253906 -8.5625 7.109375 -8.5 C 6.960938 -8.445312 6.835938 -8.375 6.734375 -8.28125 C 6.640625 -8.1875 6.566406 -8.078125 6.515625 -7.953125 C 6.460938 -7.835938 6.425781 -7.710938 6.40625 -7.578125 L 6.40625 0 L 4.8125 0 L 4.8125 -7.375 C 4.8125 -7.769531 4.722656 -8.070312 4.546875 -8.28125 C 4.367188 -8.488281 4.085938 -8.59375 3.703125 -8.59375 C 3.347656 -8.59375 3.070312 -8.519531 2.875 -8.375 C 2.6875 -8.238281 2.546875 -8.054688 2.453125 -7.828125 L 2.453125 0 L 0.84375 0 L 0.84375 -10 Z M 2.359375 -10 "/>
</symbol>
<symbol overflow="visible" id="glyph0-8">
<path style="stroke:none;" d="M 1.5625 0 L 1.5625 -13 L 5.515625 -13 C 6.066406 -13 6.601562 -12.925781 7.125 -12.78125 C 7.644531 -12.644531 8.109375 -12.425781 8.515625 -12.125 C 8.921875 -11.832031 9.242188 -11.457031 9.484375 -11 C 9.734375 -10.539062 9.851562 -9.984375 9.84375 -9.328125 C 9.84375 -8.972656 9.785156 -8.648438 9.671875 -8.359375 C 9.566406 -8.066406 9.421875 -7.800781 9.234375 -7.5625 C 9.054688 -7.320312 8.84375 -7.109375 8.59375 -6.921875 C 8.34375 -6.742188 8.078125 -6.597656 7.796875 -6.484375 C 8.148438 -6.390625 8.472656 -6.25 8.765625 -6.0625 C 9.054688 -5.882812 9.304688 -5.671875 9.515625 -5.421875 C 9.734375 -5.171875 9.898438 -4.890625 10.015625 -4.578125 C 10.140625 -4.265625 10.203125 -3.921875 10.203125 -3.546875 C 10.210938 -2.972656 10.09375 -2.460938 9.84375 -2.015625 C 9.601562 -1.578125 9.28125 -1.207031 8.875 -0.90625 C 8.46875 -0.613281 8 -0.390625 7.46875 -0.234375 C 6.9375 -0.078125 6.382812 0 5.8125 0 Z M 3.265625 -5.703125 L 3.265625 -1.421875 L 5.859375 -1.421875 C 6.210938 -1.421875 6.546875 -1.46875 6.859375 -1.5625 C 7.179688 -1.664062 7.460938 -1.804688 7.703125 -1.984375 C 7.941406 -2.171875 8.132812 -2.394531 8.28125 -2.65625 C 8.425781 -2.914062 8.5 -3.21875 8.5 -3.5625 C 8.5 -3.90625 8.429688 -4.207031 8.296875 -4.46875 C 8.171875 -4.726562 7.992188 -4.945312 7.765625 -5.125 C 7.535156 -5.3125 7.265625 -5.453125 6.953125 -5.546875 C 6.640625 -5.648438 6.304688 -5.703125 5.953125 -5.703125 Z M 3.265625 -7.109375 L 5.609375 -7.109375 C 5.929688 -7.109375 6.242188 -7.15625 6.546875 -7.25 C 6.847656 -7.351562 7.117188 -7.5 7.359375 -7.6875 C 7.597656 -7.882812 7.789062 -8.117188 7.9375 -8.390625 C 8.082031 -8.671875 8.15625 -8.992188 8.15625 -9.359375 C 8.15625 -9.742188 8.082031 -10.078125 7.9375 -10.359375 C 7.789062 -10.640625 7.597656 -10.867188 7.359375 -11.046875 C 7.117188 -11.222656 6.84375 -11.351562 6.53125 -11.4375 C 6.21875 -11.519531 5.898438 -11.5625 5.578125 -11.5625 L 3.265625 -11.5625 Z M 3.265625 -7.109375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-9">
<path style="stroke:none;" d="M 1.109375 -5.09375 C 1.109375 -5.789062 1.210938 -6.4375 1.421875 -7.03125 C 1.628906 -7.625 1.925781 -8.140625 2.3125 -8.578125 C 2.695312 -9.023438 3.164062 -9.375 3.71875 -9.625 C 4.269531 -9.875 4.894531 -10 5.59375 -10 C 6.289062 -10 6.914062 -9.875 7.46875 -9.625 C 8.03125 -9.375 8.503906 -9.023438 8.890625 -8.578125 C 9.273438 -8.140625 9.566406 -7.625 9.765625 -7.03125 C 9.972656 -6.4375 10.078125 -5.789062 10.078125 -5.09375 L 10.078125 -4.890625 C 10.078125 -4.191406 9.972656 -3.546875 9.765625 -2.953125 C 9.566406 -2.367188 9.273438 -1.851562 8.890625 -1.40625 C 8.503906 -0.96875 8.03125 -0.625 7.46875 -0.375 C 6.914062 -0.125 6.296875 0 5.609375 0 C 4.910156 0 4.28125 -0.125 3.71875 -0.375 C 3.164062 -0.625 2.695312 -0.96875 2.3125 -1.40625 C 1.925781 -1.851562 1.628906 -2.367188 1.421875 -2.953125 C 1.210938 -3.546875 1.109375 -4.191406 1.109375 -4.890625 Z M 2.796875 -4.890625 C 2.796875 -4.421875 2.851562 -3.972656 2.96875 -3.546875 C 3.082031 -3.117188 3.253906 -2.742188 3.484375 -2.421875 C 3.722656 -2.097656 4.019531 -1.84375 4.375 -1.65625 C 4.726562 -1.46875 5.140625 -1.375 5.609375 -1.375 C 6.066406 -1.375 6.46875 -1.46875 6.8125 -1.65625 C 7.164062 -1.84375 7.457031 -2.097656 7.6875 -2.421875 C 7.925781 -2.742188 8.101562 -3.117188 8.21875 -3.546875 C 8.332031 -3.972656 8.390625 -4.421875 8.390625 -4.890625 L 8.390625 -5.09375 C 8.390625 -5.5625 8.332031 -6.007812 8.21875 -6.4375 C 8.101562 -6.863281 7.925781 -7.238281 7.6875 -7.5625 C 7.457031 -7.882812 7.164062 -8.140625 6.8125 -8.328125 C 6.46875 -8.523438 6.0625 -8.625 5.59375 -8.625 C 5.125 -8.625 4.710938 -8.523438 4.359375 -8.328125 C 4.015625 -8.140625 3.722656 -7.882812 3.484375 -7.5625 C 3.253906 -7.238281 3.082031 -6.863281 2.96875 -6.4375 C 2.851562 -6.007812 2.796875 -5.5625 2.796875 -5.09375 Z M 2.796875 -4.890625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-10">
<path style="stroke:none;" d="M 5.578125 -12.5 L 5.578125 -10 L 9.34375 -10 L 9.34375 -8.703125 L 5.578125 -8.703125 L 5.578125 -3.375 C 5.578125 -2.988281 5.625 -2.671875 5.71875 -2.421875 C 5.820312 -2.179688 5.957031 -1.984375 6.125 -1.828125 C 6.289062 -1.679688 6.484375 -1.578125 6.703125 -1.515625 C 6.929688 -1.460938 7.171875 -1.4375 7.421875 -1.4375 C 7.597656 -1.4375 7.785156 -1.445312 7.984375 -1.46875 C 8.179688 -1.488281 8.367188 -1.515625 8.546875 -1.546875 C 8.734375 -1.578125 8.90625 -1.609375 9.0625 -1.640625 C 9.226562 -1.679688 9.363281 -1.710938 9.46875 -1.734375 L 9.703125 -0.53125 C 9.566406 -0.445312 9.394531 -0.375 9.1875 -0.3125 C 8.988281 -0.25 8.769531 -0.191406 8.53125 -0.140625 C 8.300781 -0.0976562 8.050781 -0.0625 7.78125 -0.03125 C 7.519531 -0.0078125 7.257812 0 7 0 C 6.5625 0 6.148438 -0.0625 5.765625 -0.1875 C 5.390625 -0.3125 5.0625 -0.507812 4.78125 -0.78125 C 4.5 -1.050781 4.28125 -1.398438 4.125 -1.828125 C 3.96875 -2.253906 3.890625 -2.769531 3.890625 -3.375 L 3.890625 -8.703125 L 1.296875 -8.703125 L 1.296875 -10 L 3.890625 -10 L 3.890625 -12.5 Z M 5.578125 -12.5 "/>
</symbol>
<symbol overflow="visible" id="glyph0-11">
<path style="stroke:none;" d="M 7.921875 -3.6875 L 3.484375 -3.6875 L 2.421875 0 L 0.734375 0 L 5.03125 -13 L 6.4375 -13 L 10.65625 0 L 8.96875 0 Z M 3.953125 -5.125 L 7.46875 -5.125 L 5.71875 -10.546875 Z M 3.953125 -5.125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-12">
<path style="stroke:none;" d="M 3.421875 -5.71875 L 3.421875 0 L 1.734375 0 L 1.734375 -13 L 6.046875 -13 C 6.640625 -13 7.203125 -12.914062 7.734375 -12.75 C 8.265625 -12.59375 8.726562 -12.359375 9.125 -12.046875 C 9.53125 -11.742188 9.847656 -11.363281 10.078125 -10.90625 C 10.316406 -10.457031 10.4375 -9.941406 10.4375 -9.359375 C 10.4375 -8.773438 10.316406 -8.253906 10.078125 -7.796875 C 9.847656 -7.347656 9.53125 -6.96875 9.125 -6.65625 C 8.726562 -6.351562 8.265625 -6.117188 7.734375 -5.953125 C 7.203125 -5.796875 6.640625 -5.71875 6.046875 -5.71875 Z M 3.421875 -7.09375 L 6.046875 -7.09375 C 6.429688 -7.09375 6.785156 -7.144531 7.109375 -7.25 C 7.441406 -7.351562 7.726562 -7.5 7.96875 -7.6875 C 8.21875 -7.882812 8.410156 -8.117188 8.546875 -8.390625 C 8.679688 -8.660156 8.75 -8.976562 8.75 -9.34375 C 8.75 -9.6875 8.679688 -10 8.546875 -10.28125 C 8.410156 -10.570312 8.222656 -10.816406 7.984375 -11.015625 C 7.742188 -11.210938 7.457031 -11.363281 7.125 -11.46875 C 6.789062 -11.570312 6.429688 -11.625 6.046875 -11.625 L 3.421875 -11.625 Z M 3.421875 -7.09375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-13">
<path style="stroke:none;" d="M 1.59375 -13 L 9.609375 -13 L 9.609375 -11.53125 L 6.421875 -11.53125 L 6.421875 -1.453125 L 9.609375 -1.453125 L 9.609375 0 L 1.59375 0 L 1.59375 -1.453125 L 4.703125 -1.453125 L 4.703125 -11.53125 L 1.59375 -11.53125 Z M 1.59375 -13 "/>
</symbol>
<symbol overflow="visible" id="glyph0-14">
<path style="stroke:none;" d="M 8.96875 -4.71875 L 1.984375 -4.71875 L 1.984375 -6.09375 L 8.96875 -6.09375 Z M 8.96875 -4.71875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-15">
<path style="stroke:none;" d="M 5.65625 -6.375 L 8.296875 -10 L 10.28125 -10 L 6.59375 -5.0625 L 10.375 0 L 8.421875 0 L 5.703125 -3.8125 L 2.96875 0 L 1 0 L 4.78125 -5.0625 L 1.109375 -10 L 3.046875 -10 Z M 5.65625 -6.375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-16">
<path style="stroke:none;" d="M 3.09375 -10 L 3.21875 -8.390625 C 3.570312 -8.898438 4.007812 -9.296875 4.53125 -9.578125 C 5.0625 -9.859375 5.648438 -10 6.296875 -10 C 6.804688 -10 7.269531 -9.925781 7.6875 -9.78125 C 8.113281 -9.632812 8.472656 -9.40625 8.765625 -9.09375 C 9.066406 -8.789062 9.296875 -8.398438 9.453125 -7.921875 C 9.617188 -7.453125 9.703125 -6.890625 9.703125 -6.234375 L 9.703125 0 L 8.015625 0 L 8.015625 -6.21875 C 8.015625 -6.644531 7.96875 -7.007812 7.875 -7.3125 C 7.78125 -7.625 7.632812 -7.875 7.4375 -8.0625 C 7.25 -8.25 7.015625 -8.382812 6.734375 -8.46875 C 6.460938 -8.550781 6.148438 -8.59375 5.796875 -8.59375 C 5.222656 -8.59375 4.722656 -8.453125 4.296875 -8.171875 C 3.867188 -7.890625 3.523438 -7.519531 3.265625 -7.0625 L 3.265625 0 L 1.59375 0 L 1.59375 -10 Z M 3.09375 -10 "/>
</symbol>
<symbol overflow="visible" id="glyph0-17">
<path style="stroke:none;" d="M 8.140625 -2.765625 C 8.140625 -2.960938 8.097656 -3.140625 8.015625 -3.296875 C 7.941406 -3.453125 7.8125 -3.59375 7.625 -3.71875 C 7.4375 -3.84375 7.1875 -3.960938 6.875 -4.078125 C 6.5625 -4.191406 6.175781 -4.289062 5.71875 -4.375 C 5.15625 -4.488281 4.640625 -4.625 4.171875 -4.78125 C 3.703125 -4.945312 3.300781 -5.140625 2.96875 -5.359375 C 2.644531 -5.578125 2.390625 -5.835938 2.203125 -6.140625 C 2.023438 -6.441406 1.9375 -6.789062 1.9375 -7.1875 C 1.9375 -7.570312 2.03125 -7.9375 2.21875 -8.28125 C 2.40625 -8.625 2.664062 -8.921875 3 -9.171875 C 3.34375 -9.429688 3.75 -9.632812 4.21875 -9.78125 C 4.695312 -9.925781 5.21875 -10 5.78125 -10 C 6.382812 -10 6.929688 -9.921875 7.421875 -9.765625 C 7.910156 -9.609375 8.320312 -9.390625 8.65625 -9.109375 C 9 -8.835938 9.265625 -8.519531 9.453125 -8.15625 C 9.640625 -7.789062 9.734375 -7.398438 9.734375 -6.984375 L 8.046875 -6.984375 C 8.046875 -7.179688 7.988281 -7.378906 7.875 -7.578125 C 7.769531 -7.773438 7.617188 -7.953125 7.421875 -8.109375 C 7.222656 -8.265625 6.984375 -8.390625 6.703125 -8.484375 C 6.429688 -8.578125 6.125 -8.625 5.78125 -8.625 C 5.425781 -8.625 5.113281 -8.582031 4.84375 -8.5 C 4.570312 -8.425781 4.34375 -8.320312 4.15625 -8.1875 C 3.976562 -8.0625 3.84375 -7.910156 3.75 -7.734375 C 3.664062 -7.566406 3.625 -7.390625 3.625 -7.203125 C 3.625 -7.015625 3.660156 -6.847656 3.734375 -6.703125 C 3.804688 -6.554688 3.929688 -6.421875 4.109375 -6.296875 C 4.285156 -6.179688 4.523438 -6.078125 4.828125 -5.984375 C 5.128906 -5.890625 5.507812 -5.796875 5.96875 -5.703125 C 6.582031 -5.578125 7.128906 -5.429688 7.609375 -5.265625 C 8.085938 -5.109375 8.488281 -4.914062 8.8125 -4.6875 C 9.144531 -4.457031 9.394531 -4.191406 9.5625 -3.890625 C 9.738281 -3.585938 9.828125 -3.238281 9.828125 -2.84375 C 9.828125 -2.414062 9.726562 -2.023438 9.53125 -1.671875 C 9.332031 -1.328125 9.054688 -1.03125 8.703125 -0.78125 C 8.347656 -0.53125 7.925781 -0.335938 7.4375 -0.203125 C 6.945312 -0.0664062 6.410156 0 5.828125 0 C 5.160156 0 4.5625 -0.0859375 4.03125 -0.265625 C 3.507812 -0.441406 3.066406 -0.675781 2.703125 -0.96875 C 2.347656 -1.257812 2.070312 -1.59375 1.875 -1.96875 C 1.6875 -2.351562 1.59375 -2.75 1.59375 -3.15625 L 3.28125 -3.15625 C 3.300781 -2.820312 3.390625 -2.539062 3.546875 -2.3125 C 3.710938 -2.082031 3.914062 -1.894531 4.15625 -1.75 C 4.394531 -1.613281 4.660156 -1.515625 4.953125 -1.453125 C 5.242188 -1.398438 5.535156 -1.375 5.828125 -1.375 C 6.535156 -1.375 7.09375 -1.5 7.5 -1.75 C 7.914062 -2 8.128906 -2.335938 8.140625 -2.765625 Z M 8.140625 -2.765625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-18">
<path style="stroke:none;" d="M 1.84375 -10 L 6.890625 -10 L 6.890625 -1.453125 L 10.109375 -1.453125 L 10.109375 0 L 1.84375 0 L 1.84375 -1.453125 L 5.203125 -1.453125 L 5.203125 -8.546875 L 1.84375 -8.546875 Z M 4.984375 -12 C 4.984375 -12.28125 5.066406 -12.515625 5.234375 -12.703125 C 5.398438 -12.898438 5.65625 -13 6 -13 C 6.332031 -13 6.582031 -12.898438 6.75 -12.703125 C 6.925781 -12.515625 7.015625 -12.28125 7.015625 -12 C 7.015625 -11.726562 6.925781 -11.5 6.75 -11.3125 C 6.582031 -11.132812 6.332031 -11.046875 6 -11.046875 C 5.65625 -11.046875 5.398438 -11.132812 5.234375 -11.3125 C 5.066406 -11.5 4.984375 -11.726562 4.984375 -12 Z M 4.984375 -12 "/>
</symbol>
<symbol overflow="visible" id="glyph0-19">
<path style="stroke:none;" d="M 9.90625 -4.890625 C 9.90625 -4.203125 9.820312 -3.5625 9.65625 -2.96875 C 9.488281 -2.375 9.238281 -1.851562 8.90625 -1.40625 C 8.582031 -0.96875 8.175781 -0.625 7.6875 -0.375 C 7.207031 -0.125 6.65625 0 6.03125 0 C 5.4375 0 4.90625 -0.0976562 4.4375 -0.296875 C 3.976562 -0.492188 3.585938 -0.769531 3.265625 -1.125 L 3.265625 4 L 1.578125 4 L 1.578125 -10 L 3.125 -10 L 3.203125 -8.9375 C 3.523438 -9.28125 3.921875 -9.539062 4.390625 -9.71875 C 4.859375 -9.90625 5.398438 -10 6.015625 -10 C 6.640625 -10 7.195312 -9.875 7.6875 -9.625 C 8.175781 -9.382812 8.582031 -9.046875 8.90625 -8.609375 C 9.238281 -8.179688 9.488281 -7.664062 9.65625 -7.0625 C 9.820312 -6.46875 9.90625 -5.804688 9.90625 -5.078125 Z M 8.21875 -5.171875 C 8.21875 -5.648438 8.164062 -6.101562 8.0625 -6.53125 C 7.957031 -6.96875 7.789062 -7.351562 7.5625 -7.6875 C 7.34375 -8.019531 7.0625 -8.28125 6.71875 -8.46875 C 6.382812 -8.664062 5.976562 -8.765625 5.5 -8.765625 C 4.96875 -8.765625 4.515625 -8.640625 4.140625 -8.390625 C 3.773438 -8.140625 3.484375 -7.816406 3.265625 -7.421875 L 3.265625 -2.6875 C 3.484375 -2.300781 3.773438 -1.984375 4.140625 -1.734375 C 4.503906 -1.492188 4.96875 -1.375 5.53125 -1.375 C 6 -1.375 6.398438 -1.472656 6.734375 -1.671875 C 7.078125 -1.867188 7.359375 -2.132812 7.578125 -2.46875 C 7.796875 -2.800781 7.957031 -3.179688 8.0625 -3.609375 C 8.164062 -4.046875 8.21875 -4.503906 8.21875 -4.984375 Z M 8.21875 -5.171875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-20">
<path style="stroke:none;" d="M 8.890625 -5.703125 L 3.34375 -5.703125 L 3.34375 -1.421875 L 9.8125 -1.421875 L 9.8125 0 L 1.65625 0 L 1.65625 -13 L 9.734375 -13 L 9.734375 -11.5625 L 3.34375 -11.5625 L 3.34375 -7.109375 L 8.890625 -7.109375 Z M 8.890625 -5.703125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-21">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-22">
<path style="stroke:none;" d="M 2.71875 -10 L 7.703125 -10 L 7.703125 0.03125 C 7.703125 0.664062 7.613281 1.226562 7.4375 1.71875 C 7.269531 2.207031 7.019531 2.617188 6.6875 2.953125 C 6.351562 3.296875 5.945312 3.554688 5.46875 3.734375 C 5 3.910156 4.457031 4 3.84375 4 C 3.5 4 3.175781 4 2.875 4 C 2.570312 4 2.253906 3.957031 1.921875 3.875 L 2.046875 2.484375 C 2.148438 2.492188 2.28125 2.507812 2.4375 2.53125 C 2.59375 2.5625 2.75 2.578125 2.90625 2.578125 C 3.070312 2.578125 3.226562 2.578125 3.375 2.578125 C 3.519531 2.578125 3.640625 2.578125 3.734375 2.578125 C 4.046875 2.578125 4.34375 2.535156 4.625 2.453125 C 4.90625 2.367188 5.144531 2.226562 5.34375 2.03125 C 5.550781 1.832031 5.710938 1.570312 5.828125 1.25 C 5.953125 0.925781 6.015625 0.523438 6.015625 0.046875 L 6.015625 -8.546875 L 2.71875 -8.546875 Z M 5.78125 -12.015625 C 5.78125 -12.285156 5.859375 -12.515625 6.015625 -12.703125 C 6.179688 -12.898438 6.4375 -13 6.78125 -13 C 7.125 -13 7.378906 -12.898438 7.546875 -12.703125 C 7.710938 -12.515625 7.796875 -12.285156 7.796875 -12.015625 C 7.796875 -11.742188 7.710938 -11.515625 7.546875 -11.328125 C 7.378906 -11.140625 7.125 -11.046875 6.78125 -11.046875 C 6.4375 -11.046875 6.179688 -11.140625 6.015625 -11.328125 C 5.859375 -11.515625 5.78125 -11.742188 5.78125 -12.015625 Z M 5.78125 -12.015625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-23">
<path style="stroke:none;" d="M 5.796875 -1.375 C 6.097656 -1.375 6.390625 -1.421875 6.671875 -1.515625 C 6.960938 -1.609375 7.21875 -1.738281 7.4375 -1.90625 C 7.664062 -2.070312 7.847656 -2.269531 7.984375 -2.5 C 8.128906 -2.726562 8.203125 -2.972656 8.203125 -3.234375 L 9.796875 -3.234375 C 9.796875 -2.804688 9.679688 -2.394531 9.453125 -2 C 9.234375 -1.613281 8.9375 -1.273438 8.5625 -0.984375 C 8.195312 -0.691406 7.773438 -0.453125 7.296875 -0.265625 C 6.816406 -0.0859375 6.316406 0 5.796875 0 C 5.046875 0 4.390625 -0.128906 3.828125 -0.390625 C 3.265625 -0.648438 2.796875 -1 2.421875 -1.4375 C 2.054688 -1.882812 1.773438 -2.394531 1.578125 -2.96875 C 1.390625 -3.550781 1.296875 -4.164062 1.296875 -4.8125 L 1.296875 -5.1875 C 1.296875 -5.832031 1.390625 -6.441406 1.578125 -7.015625 C 1.773438 -7.597656 2.054688 -8.109375 2.421875 -8.546875 C 2.796875 -8.992188 3.265625 -9.347656 3.828125 -9.609375 C 4.390625 -9.867188 5.046875 -10 5.796875 -10 C 6.378906 -10 6.910156 -9.910156 7.390625 -9.734375 C 7.878906 -9.554688 8.300781 -9.3125 8.65625 -9 C 9.019531 -8.6875 9.300781 -8.3125 9.5 -7.875 C 9.695312 -7.445312 9.796875 -6.988281 9.796875 -6.5 L 8.203125 -6.5 C 8.203125 -6.789062 8.140625 -7.0625 8.015625 -7.3125 C 7.890625 -7.570312 7.71875 -7.800781 7.5 -8 C 7.289062 -8.195312 7.035156 -8.347656 6.734375 -8.453125 C 6.441406 -8.566406 6.128906 -8.625 5.796875 -8.625 C 5.265625 -8.625 4.820312 -8.519531 4.46875 -8.3125 C 4.113281 -8.113281 3.828125 -7.847656 3.609375 -7.515625 C 3.390625 -7.191406 3.234375 -6.828125 3.140625 -6.421875 C 3.046875 -6.015625 3 -5.601562 3 -5.1875 L 3 -4.8125 C 3 -4.394531 3.046875 -3.976562 3.140625 -3.5625 C 3.234375 -3.15625 3.382812 -2.789062 3.59375 -2.46875 C 3.8125 -2.144531 4.097656 -1.878906 4.453125 -1.671875 C 4.816406 -1.472656 5.265625 -1.375 5.796875 -1.375 Z M 5.796875 -1.375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-24">
<path style="stroke:none;" d="M 4.109375 0 L 4.109375 -8.703125 L 1.390625 -8.703125 L 1.390625 -10 L 4.109375 -10 L 4.109375 -10.640625 C 4.109375 -11.210938 4.195312 -11.710938 4.375 -12.140625 C 4.5625 -12.578125 4.820312 -12.941406 5.15625 -13.234375 C 5.5 -13.535156 5.90625 -13.757812 6.375 -13.90625 C 6.851562 -14.050781 7.382812 -14.125 7.96875 -14.125 C 8.363281 -14.125 8.75 -14.085938 9.125 -14.015625 C 9.507812 -13.953125 9.90625 -13.867188 10.3125 -13.765625 L 10.109375 -12.421875 C 9.859375 -12.492188 9.566406 -12.554688 9.234375 -12.609375 C 8.910156 -12.660156 8.554688 -12.6875 8.171875 -12.6875 C 7.390625 -12.6875 6.796875 -12.515625 6.390625 -12.171875 C 5.992188 -11.835938 5.796875 -11.316406 5.796875 -10.609375 L 5.796875 -10 L 9.59375 -10 L 9.59375 -8.703125 L 5.796875 -8.703125 L 5.796875 0 Z M 4.109375 0 "/>
</symbol>
<symbol overflow="visible" id="glyph0-25">
<path style="stroke:none;" d="M 4.546875 -4.640625 L 3.296875 -3.453125 L 3.296875 0 L 1.609375 0 L 1.609375 -14 L 3.296875 -14 L 3.296875 -5.515625 L 4.40625 -6.71875 L 7.640625 -10 L 9.6875 -10 L 5.703125 -5.828125 L 10.296875 0 L 8.15625 0 Z M 4.546875 -4.640625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-26">
<path style="stroke:none;" d="M 1.28125 -5.078125 C 1.28125 -5.804688 1.367188 -6.46875 1.546875 -7.0625 C 1.722656 -7.664062 1.976562 -8.179688 2.3125 -8.609375 C 2.65625 -9.046875 3.070312 -9.382812 3.5625 -9.625 C 4.0625 -9.875 4.628906 -10 5.265625 -10 C 5.847656 -10 6.359375 -9.898438 6.796875 -9.703125 C 7.242188 -9.503906 7.632812 -9.21875 7.96875 -8.84375 L 8.046875 -10 L 9.59375 -10 L 9.59375 4 L 7.90625 4 L 7.90625 -1.078125 C 7.570312 -0.734375 7.1875 -0.46875 6.75 -0.28125 C 6.3125 -0.09375 5.8125 0 5.25 0 C 4.613281 0 4.050781 -0.125 3.5625 -0.375 C 3.070312 -0.625 2.65625 -0.96875 2.3125 -1.40625 C 1.976562 -1.851562 1.722656 -2.375 1.546875 -2.96875 C 1.367188 -3.5625 1.28125 -4.203125 1.28125 -4.890625 Z M 2.96875 -4.890625 C 2.96875 -4.421875 3.019531 -3.972656 3.125 -3.546875 C 3.226562 -3.128906 3.390625 -2.757812 3.609375 -2.4375 C 3.828125 -2.113281 4.101562 -1.851562 4.4375 -1.65625 C 4.78125 -1.46875 5.1875 -1.375 5.65625 -1.375 C 6.195312 -1.375 6.648438 -1.492188 7.015625 -1.734375 C 7.378906 -1.972656 7.675781 -2.28125 7.90625 -2.65625 L 7.90625 -7.375 C 7.789062 -7.5625 7.65625 -7.726562 7.5 -7.875 C 7.351562 -8.019531 7.1875 -8.148438 7 -8.265625 C 6.820312 -8.378906 6.617188 -8.46875 6.390625 -8.53125 C 6.171875 -8.59375 5.929688 -8.625 5.671875 -8.625 C 5.203125 -8.625 4.796875 -8.523438 4.453125 -8.328125 C 4.117188 -8.128906 3.835938 -7.867188 3.609375 -7.546875 C 3.390625 -7.222656 3.226562 -6.847656 3.125 -6.421875 C 3.019531 -5.992188 2.96875 -5.546875 2.96875 -5.078125 Z M 2.96875 -4.890625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-27">
<path style="stroke:none;" d="M 7.984375 -1.359375 C 7.660156 -0.867188 7.25 -0.519531 6.75 -0.3125 C 6.257812 -0.101562 5.691406 0 5.046875 0 C 4.535156 0 4.066406 -0.078125 3.640625 -0.234375 C 3.222656 -0.398438 2.863281 -0.648438 2.5625 -0.984375 C 2.269531 -1.328125 2.039062 -1.757812 1.875 -2.28125 C 1.71875 -2.8125 1.640625 -3.441406 1.640625 -4.171875 L 1.640625 -10 L 3.328125 -10 L 3.328125 -4.15625 C 3.328125 -3.625 3.367188 -3.179688 3.453125 -2.828125 C 3.535156 -2.472656 3.660156 -2.191406 3.828125 -1.984375 C 4.003906 -1.773438 4.210938 -1.628906 4.453125 -1.546875 C 4.703125 -1.460938 4.988281 -1.421875 5.3125 -1.421875 C 6 -1.421875 6.550781 -1.554688 6.96875 -1.828125 C 7.394531 -2.109375 7.710938 -2.488281 7.921875 -2.96875 L 7.921875 -10 L 9.625 -10 L 9.625 0 L 8.09375 0 Z M 7.984375 -1.359375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-28">
<path style="stroke:none;" d="M 3.265625 -8.375 C 3.617188 -8.882812 4.054688 -9.28125 4.578125 -9.5625 C 5.097656 -9.851562 5.675781 -10 6.3125 -10 C 6.832031 -10 7.300781 -9.925781 7.71875 -9.78125 C 8.144531 -9.632812 8.503906 -9.398438 8.796875 -9.078125 C 9.097656 -8.765625 9.328125 -8.367188 9.484375 -7.890625 C 9.648438 -7.410156 9.734375 -6.84375 9.734375 -6.1875 L 9.734375 0 L 8.046875 0 L 8.046875 -6.21875 C 8.046875 -7.019531 7.851562 -7.613281 7.46875 -8 C 7.082031 -8.394531 6.53125 -8.59375 5.8125 -8.59375 C 5.269531 -8.59375 4.78125 -8.457031 4.34375 -8.1875 C 3.90625 -7.925781 3.546875 -7.578125 3.265625 -7.140625 L 3.265625 0 L 1.59375 0 L 1.59375 -14 L 3.265625 -14 Z M 3.265625 -8.375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-29">
<path style="stroke:none;" d="M 1.265625 -5.078125 C 1.265625 -5.804688 1.359375 -6.46875 1.546875 -7.0625 C 1.734375 -7.664062 2 -8.179688 2.34375 -8.609375 C 2.6875 -9.046875 3.097656 -9.382812 3.578125 -9.625 C 4.066406 -9.875 4.613281 -10 5.21875 -10 C 5.800781 -10 6.3125 -9.898438 6.75 -9.703125 C 7.195312 -9.503906 7.582031 -9.21875 7.90625 -8.84375 L 7.90625 -14 L 9.59375 -14 L 9.59375 0 L 8.046875 0 L 7.96875 -1.046875 C 7.632812 -0.703125 7.238281 -0.441406 6.78125 -0.265625 C 6.332031 -0.0859375 5.804688 0 5.203125 0 C 4.597656 0 4.054688 -0.125 3.578125 -0.375 C 3.097656 -0.625 2.6875 -0.96875 2.34375 -1.40625 C 2 -1.851562 1.734375 -2.375 1.546875 -2.96875 C 1.359375 -3.5625 1.265625 -4.203125 1.265625 -4.890625 Z M 2.953125 -4.796875 C 2.953125 -4.316406 3.003906 -3.863281 3.109375 -3.4375 C 3.210938 -3.007812 3.367188 -2.628906 3.578125 -2.296875 C 3.796875 -1.972656 4.070312 -1.71875 4.40625 -1.53125 C 4.75 -1.34375 5.148438 -1.25 5.609375 -1.25 C 5.898438 -1.25 6.160156 -1.28125 6.390625 -1.34375 C 6.617188 -1.40625 6.828125 -1.5 7.015625 -1.625 C 7.203125 -1.75 7.367188 -1.894531 7.515625 -2.0625 C 7.660156 -2.238281 7.789062 -2.4375 7.90625 -2.65625 L 7.90625 -7.203125 C 7.6875 -7.597656 7.390625 -7.925781 7.015625 -8.1875 C 6.648438 -8.445312 6.191406 -8.578125 5.640625 -8.578125 C 5.160156 -8.578125 4.75 -8.476562 4.40625 -8.28125 C 4.070312 -8.09375 3.796875 -7.832031 3.578125 -7.5 C 3.367188 -7.164062 3.210938 -6.78125 3.109375 -6.34375 C 3.003906 -5.914062 2.953125 -5.460938 2.953125 -4.984375 Z M 2.953125 -4.796875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-30">
<path style="stroke:none;" d="M 5.453125 -2.453125 L 5.609375 -1.84375 L 5.765625 -2.453125 L 8.53125 -10 L 10.25 -10 L 6.234375 0 L 4.953125 0 L 0.890625 -10 L 2.625 -10 Z M 5.453125 -2.453125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-31">
<path style="stroke:none;" d="M 5.21875 -3.546875 L 5.65625 -2.34375 L 8.65625 -10 L 10.546875 -10 L 5.546875 1.515625 C 5.429688 1.765625 5.28125 2.035156 5.09375 2.328125 C 4.914062 2.617188 4.695312 2.882812 4.4375 3.125 C 4.1875 3.363281 3.890625 3.566406 3.546875 3.734375 C 3.210938 3.910156 2.820312 4 2.375 4 C 2.300781 4 2.210938 4 2.109375 4 C 2.015625 4 1.914062 3.988281 1.8125 3.96875 C 1.71875 3.957031 1.628906 3.941406 1.546875 3.921875 C 1.460938 3.910156 1.394531 3.898438 1.34375 3.890625 L 1.609375 2.5 C 1.648438 2.5 1.707031 2.5 1.78125 2.5 C 1.851562 2.5 1.929688 2.5 2.015625 2.5 C 2.097656 2.5 2.175781 2.5 2.25 2.5 C 2.320312 2.5 2.378906 2.5 2.421875 2.5 C 2.648438 2.5 2.859375 2.429688 3.046875 2.296875 C 3.242188 2.171875 3.414062 2.019531 3.5625 1.84375 C 3.707031 1.675781 3.832031 1.5 3.9375 1.3125 C 4.050781 1.125 4.132812 0.96875 4.1875 0.84375 L 4.875 -0.46875 L 0.625 -10 L 2.5 -10 Z M 5.21875 -3.546875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-32">
<path style="stroke:none;" d="M 5.953125 -13 L 5.765625 -9.65625 L 4.5 -9.65625 L 4.515625 -12.84375 L 4.515625 -14 L 5.953125 -14 Z M 5.953125 -13 "/>
</symbol>
<symbol overflow="visible" id="glyph0-33">
<path style="stroke:none;" d="M 3.078125 -3.625 L 3.28125 -2.1875 L 3.53125 -3.625 L 5.109375 -10 L 6.1875 -10 L 7.765625 -3.625 L 8.015625 -2.046875 L 8.265625 -3.625 L 9.359375 -10 L 10.859375 -10 L 8.765625 0 L 7.4375 0 L 5.890625 -6.125 L 5.640625 -7.6875 L 5.390625 -6.125 L 3.859375 0 L 2.53125 0 L 0.4375 -10 L 1.9375 -10 Z M 3.078125 -3.625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-34">
<path style="stroke:none;" d="M 8.96875 -5.6875 L 3.453125 -5.6875 L 3.453125 0 L 1.734375 0 L 1.734375 -13 L 9.890625 -13 L 9.890625 -11.5625 L 3.453125 -11.5625 L 3.453125 -7.125 L 8.96875 -7.125 Z M 8.96875 -5.6875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-35">
<path style="stroke:none;" d="M 9.953125 -4.890625 C 9.953125 -4.203125 9.863281 -3.5625 9.6875 -2.96875 C 9.519531 -2.375 9.269531 -1.851562 8.9375 -1.40625 C 8.613281 -0.96875 8.207031 -0.625 7.71875 -0.375 C 7.238281 -0.125 6.6875 0 6.0625 0 C 5.425781 0 4.875 -0.113281 4.40625 -0.34375 C 3.945312 -0.570312 3.554688 -0.894531 3.234375 -1.3125 L 3.140625 0 L 1.59375 0 L 1.59375 -14 L 3.28125 -14 L 3.28125 -8.765625 C 3.601562 -9.160156 3.992188 -9.460938 4.453125 -9.671875 C 4.910156 -9.890625 5.441406 -10 6.046875 -10 C 6.679688 -10 7.238281 -9.875 7.71875 -9.625 C 8.207031 -9.382812 8.613281 -9.046875 8.9375 -8.609375 C 9.269531 -8.179688 9.519531 -7.664062 9.6875 -7.0625 C 9.863281 -6.46875 9.953125 -5.804688 9.953125 -5.078125 Z M 8.265625 -5.078125 C 8.265625 -5.546875 8.21875 -5.988281 8.125 -6.40625 C 8.03125 -6.832031 7.878906 -7.207031 7.671875 -7.53125 C 7.460938 -7.851562 7.191406 -8.109375 6.859375 -8.296875 C 6.523438 -8.484375 6.113281 -8.578125 5.625 -8.578125 C 5.332031 -8.578125 5.0625 -8.535156 4.8125 -8.453125 C 4.570312 -8.378906 4.359375 -8.273438 4.171875 -8.140625 C 3.984375 -8.015625 3.8125 -7.863281 3.65625 -7.6875 C 3.507812 -7.507812 3.382812 -7.316406 3.28125 -7.109375 L 3.28125 -2.921875 C 3.394531 -2.703125 3.523438 -2.503906 3.671875 -2.328125 C 3.816406 -2.148438 3.984375 -1.992188 4.171875 -1.859375 C 4.367188 -1.722656 4.585938 -1.617188 4.828125 -1.546875 C 5.078125 -1.472656 5.347656 -1.4375 5.640625 -1.4375 C 6.109375 -1.4375 6.503906 -1.523438 6.828125 -1.703125 C 7.160156 -1.890625 7.429688 -2.140625 7.640625 -2.453125 C 7.847656 -2.773438 8.003906 -3.144531 8.109375 -3.5625 C 8.210938 -3.976562 8.265625 -4.421875 8.265625 -4.890625 Z M 8.265625 -5.078125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-36">
<path style="stroke:none;" d="M 5.984375 -5.71875 L 3.328125 -5.71875 L 3.328125 0 L 1.65625 0 L 1.65625 -13 L 5.546875 -13 C 6.160156 -13 6.738281 -12.921875 7.28125 -12.765625 C 7.832031 -12.617188 8.3125 -12.394531 8.71875 -12.09375 C 9.132812 -11.789062 9.457031 -11.410156 9.6875 -10.953125 C 9.925781 -10.492188 10.046875 -9.953125 10.046875 -9.328125 C 10.046875 -8.929688 9.984375 -8.566406 9.859375 -8.234375 C 9.734375 -7.898438 9.5625 -7.597656 9.34375 -7.328125 C 9.125 -7.054688 8.863281 -6.816406 8.5625 -6.609375 C 8.257812 -6.398438 7.925781 -6.222656 7.5625 -6.078125 L 10.375 0 L 8.59375 0 Z M 3.328125 -7.09375 L 5.59375 -7.09375 C 5.96875 -7.09375 6.320312 -7.140625 6.65625 -7.234375 C 6.988281 -7.335938 7.28125 -7.484375 7.53125 -7.671875 C 7.78125 -7.867188 7.976562 -8.101562 8.125 -8.375 C 8.269531 -8.65625 8.34375 -8.972656 8.34375 -9.328125 C 8.34375 -9.710938 8.273438 -10.046875 8.140625 -10.328125 C 8.003906 -10.609375 7.8125 -10.84375 7.5625 -11.03125 C 7.3125 -11.226562 7.015625 -11.375 6.671875 -11.46875 C 6.328125 -11.570312 5.953125 -11.625 5.546875 -11.625 L 3.328125 -11.625 Z M 3.328125 -7.09375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-37">
<path style="stroke:none;" d="M 4.515625 -1.265625 C 4.515625 -1.441406 4.546875 -1.609375 4.609375 -1.765625 C 4.671875 -1.921875 4.753906 -2.054688 4.859375 -2.171875 C 4.972656 -2.296875 5.109375 -2.390625 5.265625 -2.453125 C 5.429688 -2.523438 5.625 -2.5625 5.84375 -2.5625 C 6.0625 -2.5625 6.253906 -2.523438 6.421875 -2.453125 C 6.585938 -2.390625 6.726562 -2.296875 6.84375 -2.171875 C 6.957031 -2.054688 7.039062 -1.921875 7.09375 -1.765625 C 7.15625 -1.609375 7.1875 -1.441406 7.1875 -1.265625 C 7.1875 -1.085938 7.15625 -0.921875 7.09375 -0.765625 C 7.039062 -0.609375 6.957031 -0.472656 6.84375 -0.359375 C 6.726562 -0.242188 6.585938 -0.15625 6.421875 -0.09375 C 6.253906 -0.03125 6.0625 0 5.84375 0 C 5.625 0 5.429688 -0.03125 5.265625 -0.09375 C 5.109375 -0.15625 4.972656 -0.242188 4.859375 -0.359375 C 4.753906 -0.472656 4.671875 -0.609375 4.609375 -0.765625 C 4.546875 -0.921875 4.515625 -1.085938 4.515625 -1.265625 Z M 4.515625 -1.265625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-38">
<path style="stroke:none;" d="M 9.90625 0 L 8.3125 0 L 8.3125 -5.703125 L 2.875 -5.703125 L 2.875 0 L 1.28125 0 L 1.28125 -13 L 2.875 -13 L 2.875 -7.109375 L 8.3125 -7.109375 L 8.3125 -13 L 9.90625 -13 Z M 9.90625 0 "/>
</symbol>
<symbol overflow="visible" id="glyph0-39">
<path style="stroke:none;" d="M 4.984375 -1.265625 C 4.984375 -1.441406 5.007812 -1.609375 5.0625 -1.765625 C 5.125 -1.921875 5.207031 -2.054688 5.3125 -2.171875 C 5.425781 -2.296875 5.5625 -2.390625 5.71875 -2.453125 C 5.882812 -2.523438 6.078125 -2.5625 6.296875 -2.5625 C 6.515625 -2.5625 6.707031 -2.523438 6.875 -2.453125 C 7.039062 -2.390625 7.179688 -2.296875 7.296875 -2.171875 C 7.410156 -2.054688 7.492188 -1.921875 7.546875 -1.765625 C 7.609375 -1.609375 7.640625 -1.441406 7.640625 -1.265625 C 7.640625 -1.085938 7.609375 -0.921875 7.546875 -0.765625 C 7.492188 -0.609375 7.410156 -0.472656 7.296875 -0.359375 C 7.179688 -0.242188 7.039062 -0.15625 6.875 -0.09375 C 6.707031 -0.03125 6.515625 0 6.296875 0 C 6.078125 0 5.882812 -0.03125 5.71875 -0.09375 C 5.5625 -0.15625 5.425781 -0.242188 5.3125 -0.359375 C 5.207031 -0.472656 5.125 -0.609375 5.0625 -0.765625 C 5.007812 -0.921875 4.984375 -1.085938 4.984375 -1.265625 Z M 4.984375 -8.6875 C 4.984375 -8.875 5.007812 -9.046875 5.0625 -9.203125 C 5.125 -9.359375 5.207031 -9.492188 5.3125 -9.609375 C 5.425781 -9.734375 5.5625 -9.828125 5.71875 -9.890625 C 5.882812 -9.960938 6.078125 -10 6.296875 -10 C 6.515625 -10 6.707031 -9.960938 6.875 -9.890625 C 7.039062 -9.828125 7.179688 -9.734375 7.296875 -9.609375 C 7.410156 -9.492188 7.492188 -9.359375 7.546875 -9.203125 C 7.609375 -9.046875 7.640625 -8.875 7.640625 -8.6875 C 7.640625 -8.519531 7.609375 -8.359375 7.546875 -8.203125 C 7.492188 -8.046875 7.410156 -7.910156 7.296875 -7.796875 C 7.179688 -7.679688 7.039062 -7.59375 6.875 -7.53125 C 6.707031 -7.46875 6.515625 -7.4375 6.296875 -7.4375 C 6.078125 -7.4375 5.882812 -7.46875 5.71875 -7.53125 C 5.5625 -7.59375 5.425781 -7.679688 5.3125 -7.796875 C 5.207031 -7.910156 5.125 -8.046875 5.0625 -8.203125 C 5.007812 -8.359375 4.984375 -8.519531 4.984375 -8.6875 Z M 4.984375 -8.6875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-40">
<path style="stroke:none;" d="M 4.890625 -6.09375 L 1.453125 -6.953125 L 1.953125 -8.546875 L 5.28125 -7.171875 L 5.046875 -11 L 6.671875 -11 L 6.40625 -7.125 L 9.71875 -8.484375 L 10.21875 -6.875 L 6.734375 -6.015625 L 9.0625 -3.078125 L 7.734375 -2.078125 L 5.78125 -5.375 L 3.84375 -2.15625 L 2.515625 -3.125 Z M 4.890625 -6.09375 "/>
</symbol>
</g>
</defs>
<g id="surface17060">
<path style="fill:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(40.784314%,71.764706%,13.72549%);stroke-opacity:1;stroke-miterlimit:10;" d="M 722.279541 -88.964981 C 722.279541 6.035019 722.279541 6.035019 722.279541 101.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style="fill-rule:nonzero;fill:rgb(40.784314%,71.764706%,13.72549%);fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 722.279541 104.035019 L 730.310791 92.566269 L 714.248291 92.566269 Z M 722.279541 104.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style="fill:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(40.784314%,71.764706%,13.72549%);stroke-opacity:1;stroke-miterlimit:10;" d="M 722.279541 252.035019 C 722.279541 310.535019 535.779541 310.535019 535.779541 369.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style="fill-rule:nonzero;fill:rgb(40.784314%,71.764706%,13.72549%);fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 535.779541 372.035019 L 545.439697 361.902206 L 529.560791 359.49205 Z M 535.779541 372.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 21 557 L 350 557 L 350 726 L 21 726 Z M 21 557 "/>
<path style="fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(40.784314%,71.764706%,13.72549%);stroke-opacity:1;stroke-miterlimit:10;" d="M 371.279541 384.035019 L 371.279541 374.035019 L 700.279541 374.035019 L 700.279541 384.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="26" y="580"/>
<use xlink:href="#glyph0-2" x="37" y="580"/>
<use xlink:href="#glyph0-3" x="48" y="580"/>
<use xlink:href="#glyph0-2" x="59" y="580"/>
<use xlink:href="#glyph0-4" x="70" y="580"/>
<use xlink:href="#glyph0-5" x="81" y="580"/>
<use xlink:href="#glyph0-6" x="92" y="580"/>
<use xlink:href="#glyph0-7" x="103" y="580"/>
<use xlink:href="#glyph0-8" x="114" y="580"/>
<use xlink:href="#glyph0-9" x="125" y="580"/>
<use xlink:href="#glyph0-10" x="136" y="580"/>
<use xlink:href="#glyph0-11" x="147" y="580"/>
<use xlink:href="#glyph0-12" x="158" y="580"/>
<use xlink:href="#glyph0-13" x="169" y="580"/>
<use xlink:href="#glyph0-14" x="180" y="580"/>
<use xlink:href="#glyph0-2" x="191" y="580"/>
<use xlink:href="#glyph0-15" x="202" y="580"/>
<use xlink:href="#glyph0-10" x="213" y="580"/>
<use xlink:href="#glyph0-2" x="224" y="580"/>
<use xlink:href="#glyph0-16" x="235" y="580"/>
<use xlink:href="#glyph0-17" x="246" y="580"/>
<use xlink:href="#glyph0-18" x="257" y="580"/>
<use xlink:href="#glyph0-9" x="268" y="580"/>
<use xlink:href="#glyph0-16" x="279" y="580"/>
<use xlink:href="#glyph0-17" x="290" y="580"/>
<use xlink:href="#glyph0-14" x="301" y="580"/>
<use xlink:href="#glyph0-6" x="312" y="580"/>
<use xlink:href="#glyph0-19" x="323" y="580"/>
<use xlink:href="#glyph0-18" x="334" y="580"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="26" y="624.875977"/>
<use xlink:href="#glyph0-15" x="37" y="624.875977"/>
<use xlink:href="#glyph0-10" x="48" y="624.875977"/>
<use xlink:href="#glyph0-2" x="59" y="624.875977"/>
<use xlink:href="#glyph0-16" x="70" y="624.875977"/>
<use xlink:href="#glyph0-17" x="81" y="624.875977"/>
<use xlink:href="#glyph0-18" x="92" y="624.875977"/>
<use xlink:href="#glyph0-9" x="103" y="624.875977"/>
<use xlink:href="#glyph0-16" x="114" y="624.875977"/>
<use xlink:href="#glyph0-17" x="125" y="624.875977"/>
<use xlink:href="#glyph0-21" x="136" y="624.875977"/>
<use xlink:href="#glyph0-19" x="147" y="624.875977"/>
<use xlink:href="#glyph0-5" x="158" y="624.875977"/>
<use xlink:href="#glyph0-9" x="169" y="624.875977"/>
<use xlink:href="#glyph0-22" x="180" y="624.875977"/>
<use xlink:href="#glyph0-2" x="191" y="624.875977"/>
<use xlink:href="#glyph0-23" x="202" y="624.875977"/>
<use xlink:href="#glyph0-10" x="213" y="624.875977"/>
<use xlink:href="#glyph0-21" x="224" y="624.875977"/>
<use xlink:href="#glyph0-24" x="235" y="624.875977"/>
<use xlink:href="#glyph0-9" x="246" y="624.875977"/>
<use xlink:href="#glyph0-5" x="257" y="624.875977"/>
<use xlink:href="#glyph0-21" x="268" y="624.875977"/>
<use xlink:href="#glyph0-7" x="279" y="624.875977"/>
<use xlink:href="#glyph0-6" x="290" y="624.875977"/>
<use xlink:href="#glyph0-25" x="301" y="624.875977"/>
<use xlink:href="#glyph0-2" x="312" y="624.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="26" y="647.875977"/>
<use xlink:href="#glyph0-2" x="37" y="647.875977"/>
<use xlink:href="#glyph0-26" x="48" y="647.875977"/>
<use xlink:href="#glyph0-27" x="59" y="647.875977"/>
<use xlink:href="#glyph0-2" x="70" y="647.875977"/>
<use xlink:href="#glyph0-17" x="81" y="647.875977"/>
<use xlink:href="#glyph0-10" x="92" y="647.875977"/>
<use xlink:href="#glyph0-17" x="103" y="647.875977"/>
<use xlink:href="#glyph0-21" x="114" y="647.875977"/>
<use xlink:href="#glyph0-7" x="125" y="647.875977"/>
<use xlink:href="#glyph0-9" x="136" y="647.875977"/>
<use xlink:href="#glyph0-5" x="147" y="647.875977"/>
<use xlink:href="#glyph0-2" x="158" y="647.875977"/>
<use xlink:href="#glyph0-21" x="169" y="647.875977"/>
<use xlink:href="#glyph0-3" x="180" y="647.875977"/>
<use xlink:href="#glyph0-9" x="191" y="647.875977"/>
<use xlink:href="#glyph0-9" x="202" y="647.875977"/>
<use xlink:href="#glyph0-25" x="213" y="647.875977"/>
<use xlink:href="#glyph0-21" x="224" y="647.875977"/>
<use xlink:href="#glyph0-3" x="235" y="647.875977"/>
<use xlink:href="#glyph0-18" x="246" y="647.875977"/>
<use xlink:href="#glyph0-25" x="257" y="647.875977"/>
<use xlink:href="#glyph0-2" x="268" y="647.875977"/>
<use xlink:href="#glyph0-21" x="279" y="647.875977"/>
<use xlink:href="#glyph0-18" x="290" y="647.875977"/>
<use xlink:href="#glyph0-16" x="301" y="647.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="26" y="670.875977"/>
<use xlink:href="#glyph0-28" x="37" y="670.875977"/>
<use xlink:href="#glyph0-2" x="48" y="670.875977"/>
<use xlink:href="#glyph0-21" x="59" y="670.875977"/>
<use xlink:href="#glyph0-1" x="70" y="670.875977"/>
<use xlink:href="#glyph0-2" x="81" y="670.875977"/>
<use xlink:href="#glyph0-3" x="92" y="670.875977"/>
<use xlink:href="#glyph0-2" x="103" y="670.875977"/>
<use xlink:href="#glyph0-4" x="114" y="670.875977"/>
<use xlink:href="#glyph0-5" x="125" y="670.875977"/>
<use xlink:href="#glyph0-6" x="136" y="670.875977"/>
<use xlink:href="#glyph0-7" x="147" y="670.875977"/>
<use xlink:href="#glyph0-21" x="158" y="670.875977"/>
<use xlink:href="#glyph0-8" x="169" y="670.875977"/>
<use xlink:href="#glyph0-9" x="180" y="670.875977"/>
<use xlink:href="#glyph0-10" x="191" y="670.875977"/>
<use xlink:href="#glyph0-21" x="202" y="670.875977"/>
<use xlink:href="#glyph0-11" x="213" y="670.875977"/>
<use xlink:href="#glyph0-12" x="224" y="670.875977"/>
<use xlink:href="#glyph0-13" x="235" y="670.875977"/>
<use xlink:href="#glyph0-21" x="246" y="670.875977"/>
<use xlink:href="#glyph0-6" x="257" y="670.875977"/>
<use xlink:href="#glyph0-16" x="268" y="670.875977"/>
<use xlink:href="#glyph0-29" x="279" y="670.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-4" x="26" y="693.875977"/>
<use xlink:href="#glyph0-18" x="37" y="693.875977"/>
<use xlink:href="#glyph0-30" x="48" y="693.875977"/>
<use xlink:href="#glyph0-2" x="59" y="693.875977"/>
<use xlink:href="#glyph0-21" x="70" y="693.875977"/>
<use xlink:href="#glyph0-9" x="81" y="693.875977"/>
<use xlink:href="#glyph0-19" x="92" y="693.875977"/>
<use xlink:href="#glyph0-19" x="103" y="693.875977"/>
<use xlink:href="#glyph0-9" x="114" y="693.875977"/>
<use xlink:href="#glyph0-5" x="125" y="693.875977"/>
<use xlink:href="#glyph0-10" x="136" y="693.875977"/>
<use xlink:href="#glyph0-27" x="147" y="693.875977"/>
<use xlink:href="#glyph0-16" x="158" y="693.875977"/>
<use xlink:href="#glyph0-18" x="169" y="693.875977"/>
<use xlink:href="#glyph0-10" x="180" y="693.875977"/>
<use xlink:href="#glyph0-31" x="191" y="693.875977"/>
<use xlink:href="#glyph0-21" x="202" y="693.875977"/>
<use xlink:href="#glyph0-10" x="213" y="693.875977"/>
<use xlink:href="#glyph0-9" x="224" y="693.875977"/>
<use xlink:href="#glyph0-21" x="235" y="693.875977"/>
<use xlink:href="#glyph0-27" x="246" y="693.875977"/>
<use xlink:href="#glyph0-17" x="257" y="693.875977"/>
<use xlink:href="#glyph0-2" x="268" y="693.875977"/>
<use xlink:href="#glyph0-21" x="279" y="693.875977"/>
<use xlink:href="#glyph0-18" x="290" y="693.875977"/>
<use xlink:href="#glyph0-10" x="301" y="693.875977"/>
<use xlink:href="#glyph0-32" x="312" y="693.875977"/>
<use xlink:href="#glyph0-17" x="323" y="693.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="26" y="716.875977"/>
<use xlink:href="#glyph0-6" x="37" y="716.875977"/>
<use xlink:href="#glyph0-17" x="48" y="716.875977"/>
<use xlink:href="#glyph0-18" x="59" y="716.875977"/>
<use xlink:href="#glyph0-2" x="70" y="716.875977"/>
<use xlink:href="#glyph0-5" x="81" y="716.875977"/>
</g>
<path style="fill:none;stroke-width:5;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(40.784314%,71.764706%,13.72549%);stroke-opacity:1;stroke-miterlimit:10;" d="M 722.279541 252.035019 C 722.279541 310.535019 897.779541 310.535019 897.779541 369.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style="fill-rule:nonzero;fill:rgb(40.784314%,71.764706%,13.72549%);fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:10;" d="M 897.779541 372.035019 L 904.107666 359.546738 L 888.209229 361.816269 Z M 897.779541 372.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 372 557 L 723 557 L 723 680 L 372 680 Z M 372 557 "/>
<path style="fill:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(40.784314%,71.764706%,13.72549%);stroke-opacity:1;stroke-miterlimit:10;" d="M 722.279541 384.035019 L 722.279541 374.035019 L 1073.279541 374.035019 L 1073.279541 384.035019 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="377" y="580"/>
<use xlink:href="#glyph0-2" x="388" y="580"/>
<use xlink:href="#glyph0-3" x="399" y="580"/>
<use xlink:href="#glyph0-2" x="410" y="580"/>
<use xlink:href="#glyph0-4" x="421" y="580"/>
<use xlink:href="#glyph0-5" x="432" y="580"/>
<use xlink:href="#glyph0-6" x="443" y="580"/>
<use xlink:href="#glyph0-7" x="454" y="580"/>
<use xlink:href="#glyph0-8" x="465" y="580"/>
<use xlink:href="#glyph0-9" x="476" y="580"/>
<use xlink:href="#glyph0-10" x="487" y="580"/>
<use xlink:href="#glyph0-11" x="498" y="580"/>
<use xlink:href="#glyph0-12" x="509" y="580"/>
<use xlink:href="#glyph0-13" x="520" y="580"/>
<use xlink:href="#glyph0-14" x="531" y="580"/>
<use xlink:href="#glyph0-2" x="542" y="580"/>
<use xlink:href="#glyph0-15" x="553" y="580"/>
<use xlink:href="#glyph0-10" x="564" y="580"/>
<use xlink:href="#glyph0-2" x="575" y="580"/>
<use xlink:href="#glyph0-16" x="586" y="580"/>
<use xlink:href="#glyph0-17" x="597" y="580"/>
<use xlink:href="#glyph0-18" x="608" y="580"/>
<use xlink:href="#glyph0-9" x="619" y="580"/>
<use xlink:href="#glyph0-16" x="630" y="580"/>
<use xlink:href="#glyph0-17" x="641" y="580"/>
<use xlink:href="#glyph0-14" x="652" y="580"/>
<use xlink:href="#glyph0-27" x="663" y="580"/>
<use xlink:href="#glyph0-10" x="674" y="580"/>
<use xlink:href="#glyph0-18" x="685" y="580"/>
<use xlink:href="#glyph0-3" x="696" y="580"/>
<use xlink:href="#glyph0-17" x="707" y="580"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-20" x="377" y="624.875977"/>
<use xlink:href="#glyph0-15" x="388" y="624.875977"/>
<use xlink:href="#glyph0-10" x="399" y="624.875977"/>
<use xlink:href="#glyph0-2" x="410" y="624.875977"/>
<use xlink:href="#glyph0-16" x="421" y="624.875977"/>
<use xlink:href="#glyph0-17" x="432" y="624.875977"/>
<use xlink:href="#glyph0-18" x="443" y="624.875977"/>
<use xlink:href="#glyph0-9" x="454" y="624.875977"/>
<use xlink:href="#glyph0-16" x="465" y="624.875977"/>
<use xlink:href="#glyph0-17" x="476" y="624.875977"/>
<use xlink:href="#glyph0-21" x="487" y="624.875977"/>
<use xlink:href="#glyph0-19" x="498" y="624.875977"/>
<use xlink:href="#glyph0-5" x="509" y="624.875977"/>
<use xlink:href="#glyph0-9" x="520" y="624.875977"/>
<use xlink:href="#glyph0-22" x="531" y="624.875977"/>
<use xlink:href="#glyph0-2" x="542" y="624.875977"/>
<use xlink:href="#glyph0-23" x="553" y="624.875977"/>
<use xlink:href="#glyph0-10" x="564" y="624.875977"/>
<use xlink:href="#glyph0-21" x="575" y="624.875977"/>
<use xlink:href="#glyph0-33" x="586" y="624.875977"/>
<use xlink:href="#glyph0-18" x="597" y="624.875977"/>
<use xlink:href="#glyph0-10" x="608" y="624.875977"/>
<use xlink:href="#glyph0-28" x="619" y="624.875977"/>
<use xlink:href="#glyph0-21" x="630" y="624.875977"/>
<use xlink:href="#glyph0-27" x="641" y="624.875977"/>
<use xlink:href="#glyph0-10" x="652" y="624.875977"/>
<use xlink:href="#glyph0-18" x="663" y="624.875977"/>
<use xlink:href="#glyph0-3" x="674" y="624.875977"/>
<use xlink:href="#glyph0-17" x="685" y="624.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="377" y="647.875977"/>
<use xlink:href="#glyph0-28" x="388" y="647.875977"/>
<use xlink:href="#glyph0-18" x="399" y="647.875977"/>
<use xlink:href="#glyph0-16" x="410" y="647.875977"/>
<use xlink:href="#glyph0-4" x="421" y="647.875977"/>
<use xlink:href="#glyph0-17" x="432" y="647.875977"/>
<use xlink:href="#glyph0-21" x="443" y="647.875977"/>
<use xlink:href="#glyph0-33" x="454" y="647.875977"/>
<use xlink:href="#glyph0-28" x="465" y="647.875977"/>
<use xlink:href="#glyph0-18" x="476" y="647.875977"/>
<use xlink:href="#glyph0-23" x="487" y="647.875977"/>
<use xlink:href="#glyph0-28" x="498" y="647.875977"/>
<use xlink:href="#glyph0-21" x="509" y="647.875977"/>
<use xlink:href="#glyph0-33" x="520" y="647.875977"/>
<use xlink:href="#glyph0-18" x="531" y="647.875977"/>
<use xlink:href="#glyph0-3" x="542" y="647.875977"/>
<use xlink:href="#glyph0-3" x="553" y="647.875977"/>
<use xlink:href="#glyph0-21" x="564" y="647.875977"/>
<use xlink:href="#glyph0-7" x="575" y="647.875977"/>
<use xlink:href="#glyph0-6" x="586" y="647.875977"/>
<use xlink:href="#glyph0-25" x="597" y="647.875977"/>
<use xlink:href="#glyph0-2" x="608" y="647.875977"/>
<use xlink:href="#glyph0-21" x="619" y="647.875977"/>
<use xlink:href="#glyph0-2" x="630" y="647.875977"/>
<use xlink:href="#glyph0-6" x="641" y="647.875977"/>
<use xlink:href="#glyph0-17" x="652" y="647.875977"/>
<use xlink:href="#glyph0-18" x="663" y="647.875977"/>
<use xlink:href="#glyph0-2" x="674" y="647.875977"/>
<use xlink:href="#glyph0-5" x="685" y="647.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-29" x="377" y="670.875977"/>
<use xlink:href="#glyph0-18" x="388" y="670.875977"/>
<use xlink:href="#glyph0-24" x="399" y="670.875977"/>
<use xlink:href="#glyph0-24" x="410" y="670.875977"/>
<use xlink:href="#glyph0-2" x="421" y="670.875977"/>
<use xlink:href="#glyph0-5" x="432" y="670.875977"/>
<use xlink:href="#glyph0-2" x="443" y="670.875977"/>
<use xlink:href="#glyph0-16" x="454" y="670.875977"/>
<use xlink:href="#glyph0-10" x="465" y="670.875977"/>
<use xlink:href="#glyph0-21" x="476" y="670.875977"/>
<use xlink:href="#glyph0-9" x="487" y="670.875977"/>
<use xlink:href="#glyph0-19" x="498" y="670.875977"/>
<use xlink:href="#glyph0-2" x="509" y="670.875977"/>
<use xlink:href="#glyph0-5" x="520" y="670.875977"/>
<use xlink:href="#glyph0-6" x="531" y="670.875977"/>
<use xlink:href="#glyph0-10" x="542" y="670.875977"/>
<use xlink:href="#glyph0-18" x="553" y="670.875977"/>
<use xlink:href="#glyph0-9" x="564" y="670.875977"/>
<use xlink:href="#glyph0-16" x="575" y="670.875977"/>
<use xlink:href="#glyph0-17" x="586" y="670.875977"/>
</g>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 229.5 289 L 514.5 289 L 514.5 435 L 229.5 435 Z M 229.5 289 "/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="234.5" y="312"/>
<use xlink:href="#glyph0-2" x="245.5" y="312"/>
<use xlink:href="#glyph0-3" x="256.5" y="312"/>
<use xlink:href="#glyph0-2" x="267.5" y="312"/>
<use xlink:href="#glyph0-4" x="278.5" y="312"/>
<use xlink:href="#glyph0-5" x="289.5" y="312"/>
<use xlink:href="#glyph0-6" x="300.5" y="312"/>
<use xlink:href="#glyph0-7" x="311.5" y="312"/>
<use xlink:href="#glyph0-8" x="322.5" y="312"/>
<use xlink:href="#glyph0-9" x="333.5" y="312"/>
<use xlink:href="#glyph0-10" x="344.5" y="312"/>
<use xlink:href="#glyph0-11" x="355.5" y="312"/>
<use xlink:href="#glyph0-12" x="366.5" y="312"/>
<use xlink:href="#glyph0-13" x="377.5" y="312"/>
<use xlink:href="#glyph0-14" x="388.5" y="312"/>
<use xlink:href="#glyph0-2" x="399.5" y="312"/>
<use xlink:href="#glyph0-15" x="410.5" y="312"/>
<use xlink:href="#glyph0-10" x="421.5" y="312"/>
<use xlink:href="#glyph0-2" x="432.5" y="312"/>
<use xlink:href="#glyph0-16" x="443.5" y="312"/>
<use xlink:href="#glyph0-17" x="454.5" y="312"/>
<use xlink:href="#glyph0-18" x="465.5" y="312"/>
<use xlink:href="#glyph0-9" x="476.5" y="312"/>
<use xlink:href="#glyph0-16" x="487.5" y="312"/>
<use xlink:href="#glyph0-17" x="498.5" y="312"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-34" x="234.5" y="356.875977"/>
<use xlink:href="#glyph0-6" x="245.5" y="356.875977"/>
<use xlink:href="#glyph0-7" x="256.5" y="356.875977"/>
<use xlink:href="#glyph0-18" x="267.5" y="356.875977"/>
<use xlink:href="#glyph0-3" x="278.5" y="356.875977"/>
<use xlink:href="#glyph0-31" x="289.5" y="356.875977"/>
<use xlink:href="#glyph0-21" x="300.5" y="356.875977"/>
<use xlink:href="#glyph0-9" x="311.5" y="356.875977"/>
<use xlink:href="#glyph0-24" x="322.5" y="356.875977"/>
<use xlink:href="#glyph0-21" x="333.5" y="356.875977"/>
<use xlink:href="#glyph0-19" x="344.5" y="356.875977"/>
<use xlink:href="#glyph0-5" x="355.5" y="356.875977"/>
<use xlink:href="#glyph0-9" x="366.5" y="356.875977"/>
<use xlink:href="#glyph0-22" x="377.5" y="356.875977"/>
<use xlink:href="#glyph0-2" x="388.5" y="356.875977"/>
<use xlink:href="#glyph0-23" x="399.5" y="356.875977"/>
<use xlink:href="#glyph0-10" x="410.5" y="356.875977"/>
<use xlink:href="#glyph0-17" x="421.5" y="356.875977"/>
<use xlink:href="#glyph0-21" x="432.5" y="356.875977"/>
<use xlink:href="#glyph0-33" x="443.5" y="356.875977"/>
<use xlink:href="#glyph0-28" x="454.5" y="356.875977"/>
<use xlink:href="#glyph0-18" x="465.5" y="356.875977"/>
<use xlink:href="#glyph0-23" x="476.5" y="356.875977"/>
<use xlink:href="#glyph0-28" x="487.5" y="356.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-6" x="234.5" y="379.875977"/>
<use xlink:href="#glyph0-5" x="245.5" y="379.875977"/>
<use xlink:href="#glyph0-2" x="256.5" y="379.875977"/>
<use xlink:href="#glyph0-21" x="267.5" y="379.875977"/>
<use xlink:href="#glyph0-24" x="278.5" y="379.875977"/>
<use xlink:href="#glyph0-27" x="289.5" y="379.875977"/>
<use xlink:href="#glyph0-3" x="300.5" y="379.875977"/>
<use xlink:href="#glyph0-3" x="311.5" y="379.875977"/>
<use xlink:href="#glyph0-31" x="322.5" y="379.875977"/>
<use xlink:href="#glyph0-21" x="333.5" y="379.875977"/>
<use xlink:href="#glyph0-35" x="344.5" y="379.875977"/>
<use xlink:href="#glyph0-6" x="355.5" y="379.875977"/>
<use xlink:href="#glyph0-17" x="366.5" y="379.875977"/>
<use xlink:href="#glyph0-2" x="377.5" y="379.875977"/>
<use xlink:href="#glyph0-29" x="388.5" y="379.875977"/>
<use xlink:href="#glyph0-21" x="399.5" y="379.875977"/>
<use xlink:href="#glyph0-9" x="410.5" y="379.875977"/>
<use xlink:href="#glyph0-16" x="421.5" y="379.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="234.5" y="402.875977"/>
<use xlink:href="#glyph0-2" x="245.5" y="402.875977"/>
<use xlink:href="#glyph0-3" x="256.5" y="402.875977"/>
<use xlink:href="#glyph0-2" x="267.5" y="402.875977"/>
<use xlink:href="#glyph0-4" x="278.5" y="402.875977"/>
<use xlink:href="#glyph0-5" x="289.5" y="402.875977"/>
<use xlink:href="#glyph0-6" x="300.5" y="402.875977"/>
<use xlink:href="#glyph0-7" x="311.5" y="402.875977"/>
<use xlink:href="#glyph0-8" x="322.5" y="402.875977"/>
<use xlink:href="#glyph0-9" x="333.5" y="402.875977"/>
<use xlink:href="#glyph0-10" x="344.5" y="402.875977"/>
<use xlink:href="#glyph0-11" x="355.5" y="402.875977"/>
<use xlink:href="#glyph0-12" x="366.5" y="402.875977"/>
<use xlink:href="#glyph0-13" x="377.5" y="402.875977"/>
<use xlink:href="#glyph0-21" x="388.5" y="402.875977"/>
<use xlink:href="#glyph0-6" x="399.5" y="402.875977"/>
<use xlink:href="#glyph0-16" x="410.5" y="402.875977"/>
<use xlink:href="#glyph0-29" x="421.5" y="402.875977"/>
<use xlink:href="#glyph0-21" x="432.5" y="402.875977"/>
<use xlink:href="#glyph0-2" x="443.5" y="402.875977"/>
<use xlink:href="#glyph0-15" x="454.5" y="402.875977"/>
<use xlink:href="#glyph0-10" x="465.5" y="402.875977"/>
<use xlink:href="#glyph0-2" x="476.5" y="402.875977"/>
<use xlink:href="#glyph0-16" x="487.5" y="402.875977"/>
<use xlink:href="#glyph0-29" x="498.5" y="402.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-18" x="234.5" y="425.875977"/>
<use xlink:href="#glyph0-10" x="245.5" y="425.875977"/>
<use xlink:href="#glyph0-17" x="256.5" y="425.875977"/>
<use xlink:href="#glyph0-21" x="267.5" y="425.875977"/>
<use xlink:href="#glyph0-24" x="278.5" y="425.875977"/>
<use xlink:href="#glyph0-27" x="289.5" y="425.875977"/>
<use xlink:href="#glyph0-16" x="300.5" y="425.875977"/>
<use xlink:href="#glyph0-23" x="311.5" y="425.875977"/>
<use xlink:href="#glyph0-10" x="322.5" y="425.875977"/>
<use xlink:href="#glyph0-18" x="333.5" y="425.875977"/>
<use xlink:href="#glyph0-9" x="344.5" y="425.875977"/>
<use xlink:href="#glyph0-16" x="355.5" y="425.875977"/>
<use xlink:href="#glyph0-6" x="366.5" y="425.875977"/>
<use xlink:href="#glyph0-3" x="377.5" y="425.875977"/>
<use xlink:href="#glyph0-18" x="388.5" y="425.875977"/>
<use xlink:href="#glyph0-10" x="399.5" y="425.875977"/>
<use xlink:href="#glyph0-31" x="410.5" y="425.875977"/>
</g>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(83.137255%,83.137255%,83.137255%);fill-opacity:1;" d="M 136 21 L 608 21 L 608 167 L 136 167 Z M 136 21 "/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="141" y="44"/>
<use xlink:href="#glyph0-2" x="152" y="44"/>
<use xlink:href="#glyph0-3" x="163" y="44"/>
<use xlink:href="#glyph0-2" x="174" y="44"/>
<use xlink:href="#glyph0-4" x="185" y="44"/>
<use xlink:href="#glyph0-5" x="196" y="44"/>
<use xlink:href="#glyph0-6" x="207" y="44"/>
<use xlink:href="#glyph0-7" x="218" y="44"/>
<use xlink:href="#glyph0-8" x="229" y="44"/>
<use xlink:href="#glyph0-9" x="240" y="44"/>
<use xlink:href="#glyph0-10" x="251" y="44"/>
<use xlink:href="#glyph0-11" x="262" y="44"/>
<use xlink:href="#glyph0-12" x="273" y="44"/>
<use xlink:href="#glyph0-13" x="284" y="44"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-36" x="141" y="88.875977"/>
<use xlink:href="#glyph0-9" x="152" y="88.875977"/>
<use xlink:href="#glyph0-9" x="163" y="88.875977"/>
<use xlink:href="#glyph0-10" x="174" y="88.875977"/>
<use xlink:href="#glyph0-21" x="185" y="88.875977"/>
<use xlink:href="#glyph0-19" x="196" y="88.875977"/>
<use xlink:href="#glyph0-5" x="207" y="88.875977"/>
<use xlink:href="#glyph0-9" x="218" y="88.875977"/>
<use xlink:href="#glyph0-22" x="229" y="88.875977"/>
<use xlink:href="#glyph0-2" x="240" y="88.875977"/>
<use xlink:href="#glyph0-23" x="251" y="88.875977"/>
<use xlink:href="#glyph0-10" x="262" y="88.875977"/>
<use xlink:href="#glyph0-21" x="273" y="88.875977"/>
<use xlink:href="#glyph0-33" x="284" y="88.875977"/>
<use xlink:href="#glyph0-18" x="295" y="88.875977"/>
<use xlink:href="#glyph0-10" x="306" y="88.875977"/>
<use xlink:href="#glyph0-28" x="317" y="88.875977"/>
<use xlink:href="#glyph0-21" x="328" y="88.875977"/>
<use xlink:href="#glyph0-11" x="339" y="88.875977"/>
<use xlink:href="#glyph0-12" x="350" y="88.875977"/>
<use xlink:href="#glyph0-13" x="361" y="88.875977"/>
<use xlink:href="#glyph0-37" x="372" y="88.875977"/>
<use xlink:href="#glyph0-21" x="383" y="88.875977"/>
<use xlink:href="#glyph0-13" x="394" y="88.875977"/>
<use xlink:href="#glyph0-10" x="405" y="88.875977"/>
<use xlink:href="#glyph0-21" x="416" y="88.875977"/>
<use xlink:href="#glyph0-18" x="427" y="88.875977"/>
<use xlink:href="#glyph0-17" x="438" y="88.875977"/>
<use xlink:href="#glyph0-21" x="449" y="88.875977"/>
<use xlink:href="#glyph0-16" x="460" y="88.875977"/>
<use xlink:href="#glyph0-9" x="471" y="88.875977"/>
<use xlink:href="#glyph0-10" x="482" y="88.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-5" x="141" y="111.875977"/>
<use xlink:href="#glyph0-2" x="152" y="111.875977"/>
<use xlink:href="#glyph0-23" x="163" y="111.875977"/>
<use xlink:href="#glyph0-9" x="174" y="111.875977"/>
<use xlink:href="#glyph0-7" x="185" y="111.875977"/>
<use xlink:href="#glyph0-7" x="196" y="111.875977"/>
<use xlink:href="#glyph0-2" x="207" y="111.875977"/>
<use xlink:href="#glyph0-16" x="218" y="111.875977"/>
<use xlink:href="#glyph0-29" x="229" y="111.875977"/>
<use xlink:href="#glyph0-2" x="240" y="111.875977"/>
<use xlink:href="#glyph0-29" x="251" y="111.875977"/>
<use xlink:href="#glyph0-21" x="262" y="111.875977"/>
<use xlink:href="#glyph0-10" x="273" y="111.875977"/>
<use xlink:href="#glyph0-9" x="284" y="111.875977"/>
<use xlink:href="#glyph0-21" x="295" y="111.875977"/>
<use xlink:href="#glyph0-27" x="306" y="111.875977"/>
<use xlink:href="#glyph0-17" x="317" y="111.875977"/>
<use xlink:href="#glyph0-2" x="328" y="111.875977"/>
<use xlink:href="#glyph0-21" x="339" y="111.875977"/>
<use xlink:href="#glyph0-18" x="350" y="111.875977"/>
<use xlink:href="#glyph0-10" x="361" y="111.875977"/>
<use xlink:href="#glyph0-17" x="372" y="111.875977"/>
<use xlink:href="#glyph0-21" x="383" y="111.875977"/>
<use xlink:href="#glyph0-5" x="394" y="111.875977"/>
<use xlink:href="#glyph0-2" x="405" y="111.875977"/>
<use xlink:href="#glyph0-26" x="416" y="111.875977"/>
<use xlink:href="#glyph0-27" x="427" y="111.875977"/>
<use xlink:href="#glyph0-2" x="438" y="111.875977"/>
<use xlink:href="#glyph0-17" x="449" y="111.875977"/>
<use xlink:href="#glyph0-10" x="460" y="111.875977"/>
<use xlink:href="#glyph0-17" x="471" y="111.875977"/>
<use xlink:href="#glyph0-21" x="482" y="111.875977"/>
<use xlink:href="#glyph0-29" x="493" y="111.875977"/>
<use xlink:href="#glyph0-18" x="504" y="111.875977"/>
<use xlink:href="#glyph0-5" x="515" y="111.875977"/>
<use xlink:href="#glyph0-2" x="526" y="111.875977"/>
<use xlink:href="#glyph0-23" x="537" y="111.875977"/>
<use xlink:href="#glyph0-10" x="548" y="111.875977"/>
<use xlink:href="#glyph0-3" x="559" y="111.875977"/>
<use xlink:href="#glyph0-31" x="570" y="111.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-6" x="141" y="134.875977"/>
<use xlink:href="#glyph0-16" x="152" y="134.875977"/>
<use xlink:href="#glyph0-29" x="163" y="134.875977"/>
<use xlink:href="#glyph0-21" x="174" y="134.875977"/>
<use xlink:href="#glyph0-35" x="185" y="134.875977"/>
<use xlink:href="#glyph0-2" x="196" y="134.875977"/>
<use xlink:href="#glyph0-10" x="207" y="134.875977"/>
<use xlink:href="#glyph0-10" x="218" y="134.875977"/>
<use xlink:href="#glyph0-2" x="229" y="134.875977"/>
<use xlink:href="#glyph0-5" x="240" y="134.875977"/>
<use xlink:href="#glyph0-21" x="251" y="134.875977"/>
<use xlink:href="#glyph0-10" x="262" y="134.875977"/>
<use xlink:href="#glyph0-9" x="273" y="134.875977"/>
<use xlink:href="#glyph0-21" x="284" y="134.875977"/>
<use xlink:href="#glyph0-27" x="295" y="134.875977"/>
<use xlink:href="#glyph0-17" x="306" y="134.875977"/>
<use xlink:href="#glyph0-2" x="317" y="134.875977"/>
<use xlink:href="#glyph0-21" x="328" y="134.875977"/>
<use xlink:href="#glyph0-6" x="339" y="134.875977"/>
<use xlink:href="#glyph0-10" x="350" y="134.875977"/>
<use xlink:href="#glyph0-21" x="361" y="134.875977"/>
<use xlink:href="#glyph0-3" x="372" y="134.875977"/>
<use xlink:href="#glyph0-2" x="383" y="134.875977"/>
<use xlink:href="#glyph0-6" x="394" y="134.875977"/>
<use xlink:href="#glyph0-17" x="405" y="134.875977"/>
<use xlink:href="#glyph0-10" x="416" y="134.875977"/>
<use xlink:href="#glyph0-21" x="427" y="134.875977"/>
<use xlink:href="#glyph0-1" x="438" y="134.875977"/>
<use xlink:href="#glyph0-2" x="449" y="134.875977"/>
<use xlink:href="#glyph0-3" x="460" y="134.875977"/>
<use xlink:href="#glyph0-2" x="471" y="134.875977"/>
<use xlink:href="#glyph0-4" x="482" y="134.875977"/>
<use xlink:href="#glyph0-5" x="493" y="134.875977"/>
<use xlink:href="#glyph0-6" x="504" y="134.875977"/>
<use xlink:href="#glyph0-7" x="515" y="134.875977"/>
<use xlink:href="#glyph0-8" x="526" y="134.875977"/>
<use xlink:href="#glyph0-9" x="537" y="134.875977"/>
<use xlink:href="#glyph0-10" x="548" y="134.875977"/>
<use xlink:href="#glyph0-11" x="559" y="134.875977"/>
<use xlink:href="#glyph0-12" x="570" y="134.875977"/>
<use xlink:href="#glyph0-13" x="581" y="134.875977"/>
<use xlink:href="#glyph0-14" x="592" y="134.875977"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-2" x="141" y="157.875977"/>
<use xlink:href="#glyph0-15" x="152" y="157.875977"/>
<use xlink:href="#glyph0-10" x="163" y="157.875977"/>
<use xlink:href="#glyph0-2" x="174" y="157.875977"/>
<use xlink:href="#glyph0-16" x="185" y="157.875977"/>
<use xlink:href="#glyph0-17" x="196" y="157.875977"/>
<use xlink:href="#glyph0-18" x="207" y="157.875977"/>
<use xlink:href="#glyph0-9" x="218" y="157.875977"/>
<use xlink:href="#glyph0-16" x="229" y="157.875977"/>
<use xlink:href="#glyph0-17" x="240" y="157.875977"/>
<use xlink:href="#glyph0-14" x="251" y="157.875977"/>
<use xlink:href="#glyph0-6" x="262" y="157.875977"/>
<use xlink:href="#glyph0-19" x="273" y="157.875977"/>
<use xlink:href="#glyph0-18" x="284" y="157.875977"/>
</g>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(83.137255%,83.137255%,83.137255%);fill-opacity:1;" d="M 182.558594 839.890625 L 555.558594 839.890625 L 555.558594 1030.890625 L 182.558594 1030.890625 Z M 182.558594 839.890625 "/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="187.558594" y="862.890625"/>
<use xlink:href="#glyph0-2" x="198.558594" y="862.890625"/>
<use xlink:href="#glyph0-3" x="209.558594" y="862.890625"/>
<use xlink:href="#glyph0-2" x="220.558594" y="862.890625"/>
<use xlink:href="#glyph0-4" x="231.558594" y="862.890625"/>
<use xlink:href="#glyph0-5" x="242.558594" y="862.890625"/>
<use xlink:href="#glyph0-6" x="253.558594" y="862.890625"/>
<use xlink:href="#glyph0-7" x="264.558594" y="862.890625"/>
<use xlink:href="#glyph0-8" x="275.558594" y="862.890625"/>
<use xlink:href="#glyph0-9" x="286.558594" y="862.890625"/>
<use xlink:href="#glyph0-10" x="297.558594" y="862.890625"/>
<use xlink:href="#glyph0-11" x="308.558594" y="862.890625"/>
<use xlink:href="#glyph0-12" x="319.558594" y="862.890625"/>
<use xlink:href="#glyph0-13" x="330.558594" y="862.890625"/>
<use xlink:href="#glyph0-14" x="341.558594" y="862.890625"/>
<use xlink:href="#glyph0-6" x="352.558594" y="862.890625"/>
<use xlink:href="#glyph0-3" x="363.558594" y="862.890625"/>
<use xlink:href="#glyph0-3" x="374.558594" y="862.890625"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-38" x="187.558594" y="907.766602"/>
<use xlink:href="#glyph0-2" x="198.558594" y="907.766602"/>
<use xlink:href="#glyph0-5" x="209.558594" y="907.766602"/>
<use xlink:href="#glyph0-2" x="220.558594" y="907.766602"/>
<use xlink:href="#glyph0-21" x="231.558594" y="907.766602"/>
<use xlink:href="#glyph0-18" x="242.558594" y="907.766602"/>
<use xlink:href="#glyph0-16" x="253.558594" y="907.766602"/>
<use xlink:href="#glyph0-23" x="264.558594" y="907.766602"/>
<use xlink:href="#glyph0-3" x="275.558594" y="907.766602"/>
<use xlink:href="#glyph0-27" x="286.558594" y="907.766602"/>
<use xlink:href="#glyph0-29" x="297.558594" y="907.766602"/>
<use xlink:href="#glyph0-2" x="308.558594" y="907.766602"/>
<use xlink:href="#glyph0-29" x="319.558594" y="907.766602"/>
<use xlink:href="#glyph0-21" x="330.558594" y="907.766602"/>
<use xlink:href="#glyph0-6" x="341.558594" y="907.766602"/>
<use xlink:href="#glyph0-3" x="352.558594" y="907.766602"/>
<use xlink:href="#glyph0-3" x="363.558594" y="907.766602"/>
<use xlink:href="#glyph0-21" x="374.558594" y="907.766602"/>
<use xlink:href="#glyph0-6" x="385.558594" y="907.766602"/>
<use xlink:href="#glyph0-30" x="396.558594" y="907.766602"/>
<use xlink:href="#glyph0-6" x="407.558594" y="907.766602"/>
<use xlink:href="#glyph0-18" x="418.558594" y="907.766602"/>
<use xlink:href="#glyph0-3" x="429.558594" y="907.766602"/>
<use xlink:href="#glyph0-6" x="440.558594" y="907.766602"/>
<use xlink:href="#glyph0-35" x="451.558594" y="907.766602"/>
<use xlink:href="#glyph0-3" x="462.558594" y="907.766602"/>
<use xlink:href="#glyph0-2" x="473.558594" y="907.766602"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="187.558594" y="930.766602"/>
<use xlink:href="#glyph0-2" x="198.558594" y="930.766602"/>
<use xlink:href="#glyph0-3" x="209.558594" y="930.766602"/>
<use xlink:href="#glyph0-2" x="220.558594" y="930.766602"/>
<use xlink:href="#glyph0-4" x="231.558594" y="930.766602"/>
<use xlink:href="#glyph0-5" x="242.558594" y="930.766602"/>
<use xlink:href="#glyph0-6" x="253.558594" y="930.766602"/>
<use xlink:href="#glyph0-7" x="264.558594" y="930.766602"/>
<use xlink:href="#glyph0-8" x="275.558594" y="930.766602"/>
<use xlink:href="#glyph0-9" x="286.558594" y="930.766602"/>
<use xlink:href="#glyph0-10" x="297.558594" y="930.766602"/>
<use xlink:href="#glyph0-11" x="308.558594" y="930.766602"/>
<use xlink:href="#glyph0-12" x="319.558594" y="930.766602"/>
<use xlink:href="#glyph0-13" x="330.558594" y="930.766602"/>
<use xlink:href="#glyph0-21" x="341.558594" y="930.766602"/>
<use xlink:href="#glyph0-3" x="352.558594" y="930.766602"/>
<use xlink:href="#glyph0-18" x="363.558594" y="930.766602"/>
<use xlink:href="#glyph0-35" x="374.558594" y="930.766602"/>
<use xlink:href="#glyph0-5" x="385.558594" y="930.766602"/>
<use xlink:href="#glyph0-6" x="396.558594" y="930.766602"/>
<use xlink:href="#glyph0-5" x="407.558594" y="930.766602"/>
<use xlink:href="#glyph0-18" x="418.558594" y="930.766602"/>
<use xlink:href="#glyph0-2" x="429.558594" y="930.766602"/>
<use xlink:href="#glyph0-17" x="440.558594" y="930.766602"/>
<use xlink:href="#glyph0-39" x="451.558594" y="930.766602"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-40" x="187.558594" y="975.642578"/>
<use xlink:href="#glyph0-21" x="198.558594" y="975.642578"/>
<use xlink:href="#glyph0-1" x="209.558594" y="975.642578"/>
<use xlink:href="#glyph0-2" x="220.558594" y="975.642578"/>
<use xlink:href="#glyph0-3" x="231.558594" y="975.642578"/>
<use xlink:href="#glyph0-2" x="242.558594" y="975.642578"/>
<use xlink:href="#glyph0-4" x="253.558594" y="975.642578"/>
<use xlink:href="#glyph0-5" x="264.558594" y="975.642578"/>
<use xlink:href="#glyph0-6" x="275.558594" y="975.642578"/>
<use xlink:href="#glyph0-7" x="286.558594" y="975.642578"/>
<use xlink:href="#glyph0-8" x="297.558594" y="975.642578"/>
<use xlink:href="#glyph0-9" x="308.558594" y="975.642578"/>
<use xlink:href="#glyph0-10" x="319.558594" y="975.642578"/>
<use xlink:href="#glyph0-11" x="330.558594" y="975.642578"/>
<use xlink:href="#glyph0-12" x="341.558594" y="975.642578"/>
<use xlink:href="#glyph0-13" x="352.558594" y="975.642578"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-40" x="187.558594" y="998.642578"/>
<use xlink:href="#glyph0-21" x="198.558594" y="998.642578"/>
<use xlink:href="#glyph0-1" x="209.558594" y="998.642578"/>
<use xlink:href="#glyph0-2" x="220.558594" y="998.642578"/>
<use xlink:href="#glyph0-3" x="231.558594" y="998.642578"/>
<use xlink:href="#glyph0-2" x="242.558594" y="998.642578"/>
<use xlink:href="#glyph0-4" x="253.558594" y="998.642578"/>
<use xlink:href="#glyph0-5" x="264.558594" y="998.642578"/>
<use xlink:href="#glyph0-6" x="275.558594" y="998.642578"/>
<use xlink:href="#glyph0-7" x="286.558594" y="998.642578"/>
<use xlink:href="#glyph0-8" x="297.558594" y="998.642578"/>
<use xlink:href="#glyph0-9" x="308.558594" y="998.642578"/>
<use xlink:href="#glyph0-10" x="319.558594" y="998.642578"/>
<use xlink:href="#glyph0-11" x="330.558594" y="998.642578"/>
<use xlink:href="#glyph0-12" x="341.558594" y="998.642578"/>
<use xlink:href="#glyph0-13" x="352.558594" y="998.642578"/>
<use xlink:href="#glyph0-14" x="363.558594" y="998.642578"/>
<use xlink:href="#glyph0-2" x="374.558594" y="998.642578"/>
<use xlink:href="#glyph0-15" x="385.558594" y="998.642578"/>
<use xlink:href="#glyph0-10" x="396.558594" y="998.642578"/>
<use xlink:href="#glyph0-2" x="407.558594" y="998.642578"/>
<use xlink:href="#glyph0-16" x="418.558594" y="998.642578"/>
<use xlink:href="#glyph0-17" x="429.558594" y="998.642578"/>
<use xlink:href="#glyph0-18" x="440.558594" y="998.642578"/>
<use xlink:href="#glyph0-9" x="451.558594" y="998.642578"/>
<use xlink:href="#glyph0-16" x="462.558594" y="998.642578"/>
<use xlink:href="#glyph0-17" x="473.558594" y="998.642578"/>
<use xlink:href="#glyph0-14" x="484.558594" y="998.642578"/>
<use xlink:href="#glyph0-6" x="495.558594" y="998.642578"/>
<use xlink:href="#glyph0-19" x="506.558594" y="998.642578"/>
<use xlink:href="#glyph0-18" x="517.558594" y="998.642578"/>
</g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-40" x="187.558594" y="1021.642578"/>
<use xlink:href="#glyph0-21" x="198.558594" y="1021.642578"/>
<use xlink:href="#glyph0-1" x="209.558594" y="1021.642578"/>
<use xlink:href="#glyph0-2" x="220.558594" y="1021.642578"/>
<use xlink:href="#glyph0-3" x="231.558594" y="1021.642578"/>
<use xlink:href="#glyph0-2" x="242.558594" y="1021.642578"/>
<use xlink:href="#glyph0-4" x="253.558594" y="1021.642578"/>
<use xlink:href="#glyph0-5" x="264.558594" y="1021.642578"/>
<use xlink:href="#glyph0-6" x="275.558594" y="1021.642578"/>
<use xlink:href="#glyph0-7" x="286.558594" y="1021.642578"/>
<use xlink:href="#glyph0-8" x="297.558594" y="1021.642578"/>
<use xlink:href="#glyph0-9" x="308.558594" y="1021.642578"/>
<use xlink:href="#glyph0-10" x="319.558594" y="1021.642578"/>
<use xlink:href="#glyph0-11" x="330.558594" y="1021.642578"/>
<use xlink:href="#glyph0-12" x="341.558594" y="1021.642578"/>
<use xlink:href="#glyph0-13" x="352.558594" y="1021.642578"/>
<use xlink:href="#glyph0-14" x="363.558594" y="1021.642578"/>
<use xlink:href="#glyph0-2" x="374.558594" y="1021.642578"/>
<use xlink:href="#glyph0-15" x="385.558594" y="1021.642578"/>
<use xlink:href="#glyph0-10" x="396.558594" y="1021.642578"/>
<use xlink:href="#glyph0-2" x="407.558594" y="1021.642578"/>
<use xlink:href="#glyph0-16" x="418.558594" y="1021.642578"/>
<use xlink:href="#glyph0-17" x="429.558594" y="1021.642578"/>
<use xlink:href="#glyph0-18" x="440.558594" y="1021.642578"/>
<use xlink:href="#glyph0-9" x="451.558594" y="1021.642578"/>
<use xlink:href="#glyph0-16" x="462.558594" y="1021.642578"/>
<use xlink:href="#glyph0-17" x="473.558594" y="1021.642578"/>
<use xlink:href="#glyph0-14" x="484.558594" y="1021.642578"/>
<use xlink:href="#glyph0-27" x="495.558594" y="1021.642578"/>
<use xlink:href="#glyph0-10" x="506.558594" y="1021.642578"/>
<use xlink:href="#glyph0-18" x="517.558594" y="1021.642578"/>
<use xlink:href="#glyph0-3" x="528.558594" y="1021.642578"/>
<use xlink:href="#glyph0-17" x="539.558594" y="1021.642578"/>
</g>
<path style="fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(46.666667%,46.666667%,46.666667%);stroke-opacity:1;stroke-dasharray:2,8;stroke-miterlimit:10;" d="M 546.756104 547.035019 C 563.064697 589.30455 584.205322 624.601425 610.181885 652.925644 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(46.666667%,46.666667%,46.666667%);fill-opacity:1;" d="M 259.902344 835.890625 L 258.199219 823 L 247.207031 833.078125 Z M 259.902344 835.890625 "/>
<path style="fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke:rgb(46.666667%,46.666667%,46.666667%);stroke-opacity:1;stroke-dasharray:2,8;stroke-miterlimit:10;" d="M 893.275635 501.035019 C 868.576416 582.695175 844.552979 633.324081 821.205322 652.925644 " transform="matrix(1,0,0,1,-350.279541,182.964981)"/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(46.666667%,46.666667%,46.666667%);fill-opacity:1;" d="M 470.925781 835.890625 L 483.875 834.753906 L 474.285156 823.332031 Z M 470.925781 835.890625 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 82 KiB