Repository: aiogram/aiogram
Pull request #975 (2022-08-13 22:38:37)

Added support of Bot API 6.2
# Description

Added full support of Bot API 6.2

## Type of change

- Breaking change (fix or feature that would cause existing functionality to not work as expected)
- Documentation (typos, code examples or any documentation update)

# Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have added tests that prove my fix is effective or that my feature works as expected
- [x] New and existing unit tests pass locally with my changes
- [x] My changes generate no new warnings or errors
- [x] My changes are compatible with minimum requirements of the project
- [x] I have made corresponding changes to the documentation


github-actions[bot]: # :x: Changelog is required!

You need to add a brief description of the changes to the `CHANGES` directory.

For example, you can run `towncrier create <issue>.<type>` to create a file in the change directory and then write a description on that file.

Read more at [Towncrier docs](https://towncrier.readthedocs.io/en/latest/quickstart.html#creating-news-fragments)
codecov[bot]: # [Codecov](https://codecov.io/gh/aiogram/aiogram/pull/975?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) Report
> Merging [#975](https://codecov.io/gh/aiogram/aiogram/pull/975?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) (8da2286) into [dev-3.x](https://codecov.io/gh/aiogram/aiogram/commit/4315ecf1a242eefbe6ad1fdba33acedebf555ac0?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) (4315ecf) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/aiogram/aiogram/pull/975/graphs/tree.svg?width=650&height=150&src=pr&token=cFqEr3p9MX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram)](https://codecov.io/gh/aiogram/aiogram/pull/975?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram)

```diff
@@            Coverage Diff            @@
##           dev-3.x      #975   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          302       303    +1     
  Lines         8175      8210   +35     
=========================================
+ Hits          8175      8210   +35     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `100.00% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/aiogram/aiogram/pull/975?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) | Coverage Δ | |
|---|---|---|
| [aiogram/methods/get\_chat\_administrators.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2dldF9jaGF0X2FkbWluaXN0cmF0b3JzLnB5) | `100.00% <ø> (ø)` | |
| [aiogram/methods/get\_game\_high\_scores.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2dldF9nYW1lX2hpZ2hfc2NvcmVzLnB5) | `100.00% <ø> (ø)` | |
| [aiogram/methods/get\_my\_commands.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2dldF9teV9jb21tYW5kcy5weQ==) | `100.00% <ø> (ø)` | |
| [aiogram/methods/get\_updates.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2dldF91cGRhdGVzLnB5) | `100.00% <ø> (ø)` | |
| [aiogram/types/keyboard\_button.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS90eXBlcy9rZXlib2FyZF9idXR0b24ucHk=) | `100.00% <ø> (ø)` | |
| [aiogram/\_\_init\_\_.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9fX2luaXRfXy5weQ==) | `100.00% <100.00%> (ø)` | |
| [aiogram/client/bot.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9jbGllbnQvYm90LnB5) | `100.00% <100.00%> (ø)` | |
| [aiogram/methods/\_\_init\_\_.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL19faW5pdF9fLnB5) | `100.00% <100.00%> (ø)` | |
| [aiogram/methods/answer\_inline\_query.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2Fuc3dlcl9pbmxpbmVfcXVlcnkucHk=) | `100.00% <100.00%> (ø)` | |
| [aiogram/methods/answer\_shipping\_query.py](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2Fuc3dlcl9zaGlwcGluZ19xdWVyeS5weQ==) | `100.00% <100.00%> (ø)` | |
| ... and [35 more](https://codecov.io/gh/aiogram/aiogram/pull/975/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) | |


Patch:
diff --git a/.apiversion b/.apiversion
index a435f5a5..0cda48ac 100644
--- a/.apiversion
+++ b/.apiversion
@@ -1,1 +1,1 @@
-6.1
+6.2
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 98dda96a..2c59c647 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,12 +4,18 @@ repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks
     rev: v4.2.0
     hooks:
-      - id: end-of-file-fixer
-      - id: trailing-whitespace
-      - id: check-merge-conflict
+      - id: "trailing-whitespace"
+      - id: "check-case-conflict"
+      - id: "check-merge-conflict"
+      - id: "debug-statements"
+      - id: "end-of-file-fixer"
+      - id: "mixed-line-ending"
+      - id: "check-yaml"
+      - id: "detect-private-key"
+      - id: "check-toml"
 
   - repo: https://github.com/psf/black
-    rev: 22.3.0
+    rev: 22.6.0
     hooks:
       - id: black
         files: &files '^(aiogram|tests|examples)'
@@ -20,9 +26,15 @@ repos:
       - id: isort
         additional_dependencies: [ toml ]
         files: *files
+
   - repo: https://gitlab.com/pycqa/flake8
     rev: 3.9.2
     hooks:
       - id: flake8
         args: [ '--config=.flake8' ]
         files: *files
+
+  - repo: https://github.com/floatingpurr/sync_with_poetry
+    rev: 0.2.0
+    hooks:
+      - id: sync_with_poetry
diff --git a/CHANGES/803.feature b/CHANGES/803.feature.rst
similarity index 100%
rename from CHANGES/803.feature
rename to CHANGES/803.feature.rst
diff --git a/CHANGES/975.misc.rst b/CHANGES/975.misc.rst
new file mode 100644
index 00000000..daf4d5bc
--- /dev/null
+++ b/CHANGES/975.misc.rst
@@ -0,0 +1,1 @@
+Added full support of `Bot API 6.2 <https://core.telegram.org/bots/api-changelog#august-12-2022>`_
diff --git a/README.rst b/README.rst
index d0ad453c..58ee0d13 100644
--- a/README.rst
+++ b/README.rst
@@ -13,7 +13,7 @@ aiogram |beta badge|
     :target: https://pypi.python.org/pypi/aiogram
     :alt: Supported python versions
 
-.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-6.1-blue.svg?logo=telegram
+.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-6.2-blue.svg?logo=telegram
     :target: https://core.telegram.org/bots/api
     :alt: Telegram Bot API
 
diff --git a/aiogram/__init__.py b/aiogram/__init__.py
index 80baacbc..a0c5948c 100644
--- a/aiogram/__init__.py
+++ b/aiogram/__init__.py
@@ -36,4 +36,4 @@ __all__ = (
 )
 
 __version__ = "3.0.0b4"
-__api_version__ = "6.1"
+__api_version__ = "6.2"
diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py
index 632d5e54..d8762dba 100644
--- a/aiogram/client/bot.py
+++ b/aiogram/client/bot.py
@@ -57,6 +57,7 @@ from ..methods import (
     GetChatMemberCount,
     GetChatMembersCount,
     GetChatMenuButton,
+    GetCustomEmojiStickers,
     GetFile,
     GetGameHighScores,
     GetMe,
@@ -152,6 +153,7 @@ from ..types import (
     ReplyKeyboardRemove,
     SentWebAppMessage,
     ShippingOption,
+    Sticker,
     StickerSet,
     Update,
     User,
@@ -290,7 +292,8 @@ class Bot(ContextInstanceMixin["Bot"]):
 
         try:
             if isinstance(destination, (str, pathlib.Path)):
-                return await self.__download_file(destination=destination, stream=stream)
+                await self.__download_file(destination=destination, stream=stream)
+                return None
             else:
                 return await self.__download_file_binary_io(
                     destination=destination, seek=seek, stream=stream
@@ -383,7 +386,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         request_timeout: Optional[int] = None,
     ) -> List[Update]:
         """
-        Use this method to receive incoming updates using long polling (`wiki <https://en.wikipedia.org/wiki/Push_technology#Long_polling>`_). An Array of :class:`aiogram.types.update.Update` objects is returned.
+        Use this method to receive incoming updates using long polling (`wiki <https://en.wikipedia.org/wiki/Push_technology#Long_polling>`_). Returns an Array of :class:`aiogram.types.update.Update` objects.
 
          **Notes**
 
@@ -398,7 +401,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param timeout: Timeout in seconds for long polling. Defaults to 0, i.e. usual short polling. Should be positive, short polling should be used for testing purposes only.
         :param allowed_updates: A JSON-serialized list of the update types you want your bot to receive. For example, specify ['message', 'edited_channel_post', 'callback_query'] to only receive updates of these types. See :class:`aiogram.types.update.Update` for a complete list of available update types. Specify an empty list to receive all update types except *chat_member* (default). If not specified, the previous setting will be used.
         :param request_timeout: Request timeout
-        :return: An Array of Update objects is returned.
+        :return: Returns an Array of Update objects.
         """
         call = GetUpdates(
             offset=offset,
@@ -570,7 +573,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -638,7 +641,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         request_timeout: Optional[int] = None,
     ) -> MessageId:
         """
-        Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. The method is analogous to the method :class:`aiogram.methods.forward_message.ForwardMessage`, but the copied message doesn't have a link to the original message. Returns the :class:`aiogram.types.message_id.MessageId` of the sent message on success.
+        Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. A quiz :class:`aiogram.methods.poll.Poll` can be copied only if the value of the field *correct_option_id* is known to the bot. The method is analogous to the method :class:`aiogram.methods.forward_message.ForwardMessage`, but the copied message doesn't have a link to the original message. Returns the :class:`aiogram.types.message_id.MessageId` of the sent message on success.
 
         Source: https://core.telegram.org/bots/api#copymessage
 
@@ -651,7 +654,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: Returns the MessageId of the sent message on success.
@@ -700,7 +703,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -757,7 +760,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -813,7 +816,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -869,11 +872,11 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param caption: Video caption (may also be used when resending videos by *file_id*), 0-1024 characters after entities parsing
         :param parse_mode: Mode for parsing entities in the video caption. See `formatting options <https://core.telegram.org/bots/api#formatting-options>`_ for more details.
         :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*
-        :param supports_streaming: Pass :code:`True`, if the uploaded video is suitable for streaming
+        :param supports_streaming: Pass :code:`True` if the uploaded video is suitable for streaming
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -934,7 +937,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -988,7 +991,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1037,7 +1040,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1076,7 +1079,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends messages `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent messages from forwarding and saving
         :param reply_to_message_id: If the messages are a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param request_timeout: Request timeout
         :return: On success, an array of Messages that were sent is returned.
         """
@@ -1123,7 +1126,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1254,7 +1257,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1306,7 +1309,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1366,11 +1369,11 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param explanation_entities: A JSON-serialized list of special entities that appear in the poll explanation, which can be specified instead of *parse_mode*
         :param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with *close_date*.
         :param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with *open_period*.
-        :param is_closed: Pass :code:`True`, if the poll needs to be immediately closed. This can be useful for poll preview.
+        :param is_closed: Pass :code:`True` if the poll needs to be immediately closed. This can be useful for poll preview.
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1420,7 +1423,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -1647,17 +1650,17 @@ class Bot(ContextInstanceMixin["Bot"]):
 
         :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)
         :param user_id: Unique identifier of the target user
-        :param is_anonymous: Pass :code:`True`, if the administrator's presence in the chat is hidden
-        :param can_manage_chat: Pass :code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege
-        :param can_post_messages: Pass :code:`True`, if the administrator can create channel posts, channels only
-        :param can_edit_messages: Pass :code:`True`, if the administrator can edit messages of other users and can pin messages, channels only
-        :param can_delete_messages: Pass :code:`True`, if the administrator can delete messages of other users
-        :param can_manage_video_chats: Pass :code:`True`, if the administrator can manage video chats
-        :param can_restrict_members: Pass :code:`True`, if the administrator can restrict, ban or unban chat members
-        :param can_promote_members: Pass :code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)
-        :param can_change_info: Pass :code:`True`, if the administrator can change chat title, photo and other settings
-        :param can_invite_users: Pass :code:`True`, if the administrator can invite new users to the chat
-        :param can_pin_messages: Pass :code:`True`, if the administrator can pin messages, supergroups only
+        :param is_anonymous: Pass :code:`True` if the administrator's presence in the chat is hidden
+        :param can_manage_chat: Pass :code:`True` if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege
+        :param can_post_messages: Pass :code:`True` if the administrator can create channel posts, channels only
+        :param can_edit_messages: Pass :code:`True` if the administrator can edit messages of other users and can pin messages, channels only
+        :param can_delete_messages: Pass :code:`True` if the administrator can delete messages of other users
+        :param can_manage_video_chats: Pass :code:`True` if the administrator can manage video chats
+        :param can_restrict_members: Pass :code:`True` if the administrator can restrict, ban or unban chat members
+        :param can_promote_members: Pass :code:`True` if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)
+        :param can_change_info: Pass :code:`True` if the administrator can change chat title, photo and other settings
+        :param can_invite_users: Pass :code:`True` if the administrator can invite new users to the chat
+        :param can_pin_messages: Pass :code:`True` if the administrator can pin messages, supergroups only
         :param request_timeout: Request timeout
         :return: Returns True on success.
         """
@@ -2020,7 +2023,7 @@ class Bot(ContextInstanceMixin["Bot"]):
 
         :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)
         :param message_id: Identifier of a message to pin
-        :param disable_notification: Pass :code:`True`, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats.
+        :param disable_notification: Pass :code:`True` if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats.
         :param request_timeout: Request timeout
         :return: Returns True on success.
         """
@@ -2125,16 +2128,13 @@ class Bot(ContextInstanceMixin["Bot"]):
         ]
     ]:
         """
-        Use this method to get a list of administrators in a chat. On success, returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned.
+        Use this method to get a list of administrators in a chat, which aren't bots. Returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects.
 
         Source: https://core.telegram.org/bots/api#getchatadministrators
 
         :param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)
         :param request_timeout: Request timeout
-        :return: On success, returns an Array of ChatMember objects that contains information
-            about all chat administrators except other bots. If the chat is a group or a
-            supergroup and no administrators were appointed, only the creator will be
-            returned.
+        :return: Returns an Array of ChatMember objects.
         """
         call = GetChatAdministrators(
             chat_id=chat_id,
@@ -2342,14 +2342,14 @@ class Bot(ContextInstanceMixin["Bot"]):
         request_timeout: Optional[int] = None,
     ) -> List[BotCommand]:
         """
-        Use this method to get the current list of the bot's commands for the given scope and user language. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success. If commands aren't set, an empty list is returned.
+        Use this method to get the current list of the bot's commands for the given scope and user language. Returns an Array of :class:`aiogram.types.bot_command.BotCommand` objects. If commands aren't set, an empty list is returned.
 
         Source: https://core.telegram.org/bots/api#getmycommands
 
         :param scope: A JSON-serialized object, describing scope of users. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.
         :param language_code: A two-letter ISO 639-1 language code or an empty string
         :param request_timeout: Request timeout
-        :return: Returns Array of BotCommand on success. If commands aren't set, an empty list is
+        :return: Returns an Array of BotCommand objects. If commands aren't set, an empty list is
             returned.
         """
         call = GetMyCommands(
@@ -2676,7 +2676,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: Additional interface options. A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_, `custom reply keyboard <https://core.telegram.org/bots#keyboards>`_, instructions to remove reply keyboard or to force a reply from the user.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -2711,6 +2711,25 @@ class Bot(ContextInstanceMixin["Bot"]):
         )
         return await self(call, request_timeout=request_timeout)
 
+    async def get_custom_emoji_stickers(
+        self,
+        custom_emoji_ids: List[str],
+        request_timeout: Optional[int] = None,
+    ) -> List[Sticker]:
+        """
+        Use this method to get information about custom emoji stickers by their identifiers. Returns an Array of :class:`aiogram.types.sticker.Sticker` objects.
+
+        Source: https://core.telegram.org/bots/api#getcustomemojistickers
+
+        :param custom_emoji_ids: List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified.
+        :param request_timeout: Request timeout
+        :return: Returns an Array of Sticker objects.
+        """
+        call = GetCustomEmojiStickers(
+            custom_emoji_ids=custom_emoji_ids,
+        )
+        return await self(call, request_timeout=request_timeout)
+
     async def upload_sticker_file(
         self,
         user_id: int,
@@ -2742,7 +2761,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         png_sticker: Optional[Union[InputFile, str]] = None,
         tgs_sticker: Optional[InputFile] = None,
         webm_sticker: Optional[InputFile] = None,
-        contains_masks: Optional[bool] = None,
+        sticker_type: Optional[str] = None,
         mask_position: Optional[MaskPosition] = None,
         request_timeout: Optional[int] = None,
     ) -> bool:
@@ -2758,7 +2777,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param png_sticker: **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More information on Sending Files » <sending-files>`
         :param tgs_sticker: **TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements
         :param webm_sticker: **WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements
-        :param contains_masks: Pass :code:`True`, if a set of mask stickers should be created
+        :param sticker_type: Type of stickers in the set, pass 'regular' or 'mask'. Custom emoji sticker sets can't be created via the Bot API at the moment. By default, a regular sticker set is created.
         :param mask_position: A JSON-serialized object for position where the mask should be placed on faces
         :param request_timeout: Request timeout
         :return: Returns True on success.
@@ -2771,7 +2790,7 @@ class Bot(ContextInstanceMixin["Bot"]):
             png_sticker=png_sticker,
             tgs_sticker=tgs_sticker,
             webm_sticker=webm_sticker,
-            contains_masks=contains_masks,
+            sticker_type=sticker_type,
             mask_position=mask_position,
         )
         return await self(call, request_timeout=request_timeout)
@@ -2905,7 +2924,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param inline_query_id: Unique identifier for the answered query
         :param results: A JSON-serialized array of results for the inline query
         :param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300.
-        :param is_personal: Pass :code:`True`, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query
+        :param is_personal: Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query
         :param next_offset: Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes.
         :param switch_pm_text: If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter *switch_pm_parameter*
         :param switch_pm_parameter: `Deep-linking <https://core.telegram.org/bots#deep-linking>`_ parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only :code:`A-Z`, :code:`a-z`, :code:`0-9`, :code:`_` and :code:`-` are allowed.
@@ -3001,17 +3020,17 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param photo_size: Photo size in bytes
         :param photo_width: Photo width
         :param photo_height: Photo height
-        :param need_name: Pass :code:`True`, if you require the user's full name to complete the order
-        :param need_phone_number: Pass :code:`True`, if you require the user's phone number to complete the order
-        :param need_email: Pass :code:`True`, if you require the user's email address to complete the order
-        :param need_shipping_address: Pass :code:`True`, if you require the user's shipping address to complete the order
-        :param send_phone_number_to_provider: Pass :code:`True`, if the user's phone number should be sent to provider
-        :param send_email_to_provider: Pass :code:`True`, if the user's email address should be sent to provider
-        :param is_flexible: Pass :code:`True`, if the final price depends on the shipping method
+        :param need_name: Pass :code:`True` if you require the user's full name to complete the order
+        :param need_phone_number: Pass :code:`True` if you require the user's phone number to complete the order
+        :param need_email: Pass :code:`True` if you require the user's email address to complete the order
+        :param need_shipping_address: Pass :code:`True` if you require the user's shipping address to complete the order
+        :param send_phone_number_to_provider: Pass :code:`True` if the user's phone number should be sent to provider
+        :param send_email_to_provider: Pass :code:`True` if the user's email address should be sent to provider
+        :param is_flexible: Pass :code:`True` if the final price depends on the shipping method
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_. If empty, one 'Pay :code:`total price`' button will be shown. If not empty, the first button must be a Pay button.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -3089,13 +3108,13 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param photo_size: Photo size in bytes
         :param photo_width: Photo width
         :param photo_height: Photo height
-        :param need_name: Pass :code:`True`, if you require the user's full name to complete the order
-        :param need_phone_number: Pass :code:`True`, if you require the user's phone number to complete the order
-        :param need_email: Pass :code:`True`, if you require the user's email address to complete the order
-        :param need_shipping_address: Pass :code:`True`, if you require the user's shipping address to complete the order
-        :param send_phone_number_to_provider: Pass :code:`True`, if the user's phone number should be sent to the provider
-        :param send_email_to_provider: Pass :code:`True`, if the user's email address should be sent to the provider
-        :param is_flexible: Pass :code:`True`, if the final price depends on the shipping method
+        :param need_name: Pass :code:`True` if you require the user's full name to complete the order
+        :param need_phone_number: Pass :code:`True` if you require the user's phone number to complete the order
+        :param need_email: Pass :code:`True` if you require the user's email address to complete the order
+        :param need_shipping_address: Pass :code:`True` if you require the user's shipping address to complete the order
+        :param send_phone_number_to_provider: Pass :code:`True` if the user's phone number should be sent to the provider
+        :param send_email_to_provider: Pass :code:`True` if the user's email address should be sent to the provider
+        :param is_flexible: Pass :code:`True` if the final price depends on the shipping method
         :param request_timeout: Request timeout
         :return: Returns the created invoice link as String on success.
         """
@@ -3137,9 +3156,9 @@ class Bot(ContextInstanceMixin["Bot"]):
         Source: https://core.telegram.org/bots/api#answershippingquery
 
         :param shipping_query_id: Unique identifier for the query to be answered
-        :param ok: Specify :code:`True` if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible)
+        :param ok: Pass :code:`True` if delivery to the specified address is possible and :code:`False` if there are any problems (for example, if delivery to the specified address is not possible)
         :param shipping_options: Required if *ok* is :code:`True`. A JSON-serialized array of available shipping options.
-        :param error_message: Required if *ok* is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user.
+        :param error_message: Required if *ok* is :code:`False`. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user.
         :param request_timeout: Request timeout
         :return: On success, True is returned.
         """
@@ -3232,7 +3251,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param disable_notification: Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound.
         :param protect_content: Protects the contents of the sent message from forwarding and saving
         :param reply_to_message_id: If the message is a reply, ID of the original message
-        :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found
+        :param allow_sending_without_reply: Pass :code:`True` if the message should be sent even if the specified replied-to message is not found
         :param reply_markup: A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game.
         :param request_timeout: Request timeout
         :return: On success, the sent Message is returned.
@@ -3266,8 +3285,8 @@ class Bot(ContextInstanceMixin["Bot"]):
 
         :param user_id: User identifier
         :param score: New score, must be non-negative
-        :param force: Pass :code:`True`, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters
-        :param disable_edit_message: Pass :code:`True`, if the game message should not be automatically edited to include the current scoreboard
+        :param force: Pass :code:`True` if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters
+        :param disable_edit_message: Pass :code:`True` if the game message should not be automatically edited to include the current scoreboard
         :param chat_id: Required if *inline_message_id* is not specified. Unique identifier for the target chat
         :param message_id: Required if *inline_message_id* is not specified. Identifier of the sent message
         :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message
@@ -3296,7 +3315,7 @@ class Bot(ContextInstanceMixin["Bot"]):
         request_timeout: Optional[int] = None,
     ) -> List[GameHighScore]:
         """
-        Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. On success, returns an *Array* of :class:`aiogram.types.game_high_score.GameHighScore` objects.
+        Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. Returns an Array of :class:`aiogram.types.game_high_score.GameHighScore` objects.
 
          This method will currently return scores for the target user, plus two of their closest neighbors on each side. Will also return the top three users if the user and their neighbors are not among them. Please note that this behavior is subject to change.
 
@@ -3308,10 +3327,10 @@ class Bot(ContextInstanceMixin["Bot"]):
         :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message
         :param request_timeout: Request timeout
         :return: Will return the score of the specified user and several of their neighbors in a
-            game. On success, returns an Array of GameHighScore objects. This method will
-            currently return scores for the target user, plus two of their closest neighbors
-            on each side. Will also return the top three users if the user and their
-            neighbors are not among them.
+            game. Returns an Array of GameHighScore objects. This method will currently
+            return scores for the target user, plus two of their closest neighbors on each
+            side. Will also return the top three users if the user and their neighbors are
+            not among them.
         """
         call = GetGameHighScores(
             user_id=user_id,
diff --git a/aiogram/methods/__init__.py b/aiogram/methods/__init__.py
index 72771afc..c62577b9 100644
--- a/aiogram/methods/__init__.py
+++ b/aiogram/methods/__init__.py
@@ -34,6 +34,7 @@ from .get_chat_member import GetChatMember
 from .get_chat_member_count import GetChatMemberCount
 from .get_chat_members_count import GetChatMembersCount
 from .get_chat_menu_button import GetChatMenuButton
+from .get_custom_emoji_stickers import GetCustomEmojiStickers
 from .get_file import GetFile
 from .get_game_high_scores import GetGameHighScores
 from .get_me import GetMe
@@ -168,6 +169,7 @@ __all__ = (
     "DeleteMessage",
     "SendSticker",
     "GetStickerSet",
+    "GetCustomEmojiStickers",
     "UploadStickerFile",
     "CreateNewStickerSet",
     "AddStickerToSet",
diff --git a/aiogram/methods/answer_inline_query.py b/aiogram/methods/answer_inline_query.py
index 2e76bba3..39446226 100644
--- a/aiogram/methods/answer_inline_query.py
+++ b/aiogram/methods/answer_inline_query.py
@@ -27,7 +27,7 @@ class AnswerInlineQuery(TelegramMethod[bool]):
     cache_time: Optional[int] = None
     """The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300."""
     is_personal: Optional[bool] = None
-    """Pass :code:`True`, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query"""
+    """Pass :code:`True` if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query"""
     next_offset: Optional[str] = None
     """Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don't support pagination. Offset length can't exceed 64 bytes."""
     switch_pm_text: Optional[str] = None
diff --git a/aiogram/methods/answer_shipping_query.py b/aiogram/methods/answer_shipping_query.py
index 60da57c7..99f093a9 100644
--- a/aiogram/methods/answer_shipping_query.py
+++ b/aiogram/methods/answer_shipping_query.py
@@ -21,11 +21,11 @@ class AnswerShippingQuery(TelegramMethod[bool]):
     shipping_query_id: str
     """Unique identifier for the query to be answered"""
     ok: bool
-    """Specify :code:`True` if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible)"""
+    """Pass :code:`True` if delivery to the specified address is possible and :code:`False` if there are any problems (for example, if delivery to the specified address is not possible)"""
     shipping_options: Optional[List[ShippingOption]] = None
     """Required if *ok* is :code:`True`. A JSON-serialized array of available shipping options."""
     error_message: Optional[str] = None
-    """Required if *ok* is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user."""
+    """Required if *ok* is :code:`False`. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user."""
 
     def build_request(self, bot: Bot) -> Request:
         data: Dict[str, Any] = self.dict()
diff --git a/aiogram/methods/copy_message.py b/aiogram/methods/copy_message.py
index 9a5cddae..0b602d1e 100644
--- a/aiogram/methods/copy_message.py
+++ b/aiogram/methods/copy_message.py
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
 
 class CopyMessage(TelegramMethod[MessageId]):
     """
-    Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. The method is analogous to the method :class:`aiogram.methods.forward_message.ForwardMessage`, but the copied message doesn't have a link to the original message. Returns the :class:`aiogram.types.message_id.MessageId` of the sent message on success.
+    Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. A quiz :class:`aiogram.methods.poll.Poll` can be copied only if the value of the field *correct_option_id* is known to the bot. The method is analogous to the method :class:`aiogram.methods.forward_message.ForwardMessage`, but the copied message doesn't have a link to the original message. Returns the :class:`aiogram.types.message_id.MessageId` of the sent message on success.
 
     Source: https://core.telegram.org/bots/api#copymessage
     """
@@ -45,7 +45,7 @@ class CopyMessage(TelegramMethod[MessageId]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/create_invoice_link.py b/aiogram/methods/create_invoice_link.py
index 16208f27..5ba21a9d 100644
--- a/aiogram/methods/create_invoice_link.py
+++ b/aiogram/methods/create_invoice_link.py
@@ -45,19 +45,19 @@ class CreateInvoiceLink(TelegramMethod[str]):
     photo_height: Optional[int] = None
     """Photo height"""
     need_name: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's full name to complete the order"""
+    """Pass :code:`True` if you require the user's full name to complete the order"""
     need_phone_number: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's phone number to complete the order"""
+    """Pass :code:`True` if you require the user's phone number to complete the order"""
     need_email: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's email address to complete the order"""
+    """Pass :code:`True` if you require the user's email address to complete the order"""
     need_shipping_address: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's shipping address to complete the order"""
+    """Pass :code:`True` if you require the user's shipping address to complete the order"""
     send_phone_number_to_provider: Optional[bool] = None
-    """Pass :code:`True`, if the user's phone number should be sent to the provider"""
+    """Pass :code:`True` if the user's phone number should be sent to the provider"""
     send_email_to_provider: Optional[bool] = None
-    """Pass :code:`True`, if the user's email address should be sent to the provider"""
+    """Pass :code:`True` if the user's email address should be sent to the provider"""
     is_flexible: Optional[bool] = None
-    """Pass :code:`True`, if the final price depends on the shipping method"""
+    """Pass :code:`True` if the final price depends on the shipping method"""
 
     def build_request(self, bot: Bot) -> Request:
         data: Dict[str, Any] = self.dict()
diff --git a/aiogram/methods/create_new_sticker_set.py b/aiogram/methods/create_new_sticker_set.py
index cb77cb97..00ae4052 100644
--- a/aiogram/methods/create_new_sticker_set.py
+++ b/aiogram/methods/create_new_sticker_set.py
@@ -32,8 +32,8 @@ class CreateNewStickerSet(TelegramMethod[bool]):
     """**TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements"""
     webm_sticker: Optional[InputFile] = None
     """**WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements"""
-    contains_masks: Optional[bool] = None
-    """Pass :code:`True`, if a set of mask stickers should be created"""
+    sticker_type: Optional[str] = None
+    """Type of stickers in the set, pass 'regular' or 'mask'. Custom emoji sticker sets can't be created via the Bot API at the moment. By default, a regular sticker set is created."""
     mask_position: Optional[MaskPosition] = None
     """A JSON-serialized object for position where the mask should be placed on faces"""
 
diff --git a/aiogram/methods/get_chat_administrators.py b/aiogram/methods/get_chat_administrators.py
index adc7ed6e..d760a93e 100644
--- a/aiogram/methods/get_chat_administrators.py
+++ b/aiogram/methods/get_chat_administrators.py
@@ -31,7 +31,7 @@ class GetChatAdministrators(
     ]
 ):
     """
-    Use this method to get a list of administrators in a chat. On success, returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned.
+    Use this method to get a list of administrators in a chat, which aren't bots. Returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects.
 
     Source: https://core.telegram.org/bots/api#getchatadministrators
     """
diff --git a/aiogram/methods/get_custom_emoji_stickers.py b/aiogram/methods/get_custom_emoji_stickers.py
new file mode 100644
index 00000000..bdc265e0
--- /dev/null
+++ b/aiogram/methods/get_custom_emoji_stickers.py
@@ -0,0 +1,27 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Dict, List
+
+from ..types import Sticker
+from .base import Request, TelegramMethod
+
+if TYPE_CHECKING:
+    from ..client.bot import Bot
+
+
+class GetCustomEmojiStickers(TelegramMethod[List[Sticker]]):
+    """
+    Use this method to get information about custom emoji stickers by their identifiers. Returns an Array of :class:`aiogram.types.sticker.Sticker` objects.
+
+    Source: https://core.telegram.org/bots/api#getcustomemojistickers
+    """
+
+    __returning__ = List[Sticker]
+
+    custom_emoji_ids: List[str]
+    """List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified."""
+
+    def build_request(self, bot: Bot) -> Request:
+        data: Dict[str, Any] = self.dict()
+
+        return Request(method="getCustomEmojiStickers", data=data)
diff --git a/aiogram/methods/get_game_high_scores.py b/aiogram/methods/get_game_high_scores.py
index 67df9338..2ec6ded4 100644
--- a/aiogram/methods/get_game_high_scores.py
+++ b/aiogram/methods/get_game_high_scores.py
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
 
 class GetGameHighScores(TelegramMethod[List[GameHighScore]]):
     """
-    Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. On success, returns an *Array* of :class:`aiogram.types.game_high_score.GameHighScore` objects.
+    Use this method to get data for high score tables. Will return the score of the specified user and several of their neighbors in a game. Returns an Array of :class:`aiogram.types.game_high_score.GameHighScore` objects.
 
      This method will currently return scores for the target user, plus two of their closest neighbors on each side. Will also return the top three users if the user and their neighbors are not among them. Please note that this behavior is subject to change.
 
diff --git a/aiogram/methods/get_my_commands.py b/aiogram/methods/get_my_commands.py
index 61481a86..ed3eae1a 100644
--- a/aiogram/methods/get_my_commands.py
+++ b/aiogram/methods/get_my_commands.py
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
 
 class GetMyCommands(TelegramMethod[List[BotCommand]]):
     """
-    Use this method to get the current list of the bot's commands for the given scope and user language. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success. If commands aren't set, an empty list is returned.
+    Use this method to get the current list of the bot's commands for the given scope and user language. Returns an Array of :class:`aiogram.types.bot_command.BotCommand` objects. If commands aren't set, an empty list is returned.
 
     Source: https://core.telegram.org/bots/api#getmycommands
     """
diff --git a/aiogram/methods/get_updates.py b/aiogram/methods/get_updates.py
index ebed1d7a..219a474a 100644
--- a/aiogram/methods/get_updates.py
+++ b/aiogram/methods/get_updates.py
@@ -11,7 +11,7 @@ if TYPE_CHECKING:
 
 class GetUpdates(TelegramMethod[List[Update]]):
     """
-    Use this method to receive incoming updates using long polling (`wiki <https://en.wikipedia.org/wiki/Push_technology#Long_polling>`_). An Array of :class:`aiogram.types.update.Update` objects is returned.
+    Use this method to receive incoming updates using long polling (`wiki <https://en.wikipedia.org/wiki/Push_technology#Long_polling>`_). Returns an Array of :class:`aiogram.types.update.Update` objects.
 
      **Notes**
 
diff --git a/aiogram/methods/pin_chat_message.py b/aiogram/methods/pin_chat_message.py
index 7c1ac735..57ec7fb9 100644
--- a/aiogram/methods/pin_chat_message.py
+++ b/aiogram/methods/pin_chat_message.py
@@ -22,7 +22,7 @@ class PinChatMessage(TelegramMethod[bool]):
     message_id: int
     """Identifier of a message to pin"""
     disable_notification: Optional[bool] = None
-    """Pass :code:`True`, if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats."""
+    """Pass :code:`True` if it is not necessary to send a notification to all chat members about the new pinned message. Notifications are always disabled in channels and private chats."""
 
     def build_request(self, bot: Bot) -> Request:
         data: Dict[str, Any] = self.dict()
diff --git a/aiogram/methods/promote_chat_member.py b/aiogram/methods/promote_chat_member.py
index 4fd1a0f2..042e0afa 100644
--- a/aiogram/methods/promote_chat_member.py
+++ b/aiogram/methods/promote_chat_member.py
@@ -22,27 +22,27 @@ class PromoteChatMember(TelegramMethod[bool]):
     user_id: int
     """Unique identifier of the target user"""
     is_anonymous: Optional[bool] = None
-    """Pass :code:`True`, if the administrator's presence in the chat is hidden"""
+    """Pass :code:`True` if the administrator's presence in the chat is hidden"""
     can_manage_chat: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege"""
+    """Pass :code:`True` if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege"""
     can_post_messages: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can create channel posts, channels only"""
+    """Pass :code:`True` if the administrator can create channel posts, channels only"""
     can_edit_messages: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can edit messages of other users and can pin messages, channels only"""
+    """Pass :code:`True` if the administrator can edit messages of other users and can pin messages, channels only"""
     can_delete_messages: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can delete messages of other users"""
+    """Pass :code:`True` if the administrator can delete messages of other users"""
     can_manage_video_chats: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can manage video chats"""
+    """Pass :code:`True` if the administrator can manage video chats"""
     can_restrict_members: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can restrict, ban or unban chat members"""
+    """Pass :code:`True` if the administrator can restrict, ban or unban chat members"""
     can_promote_members: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)"""
+    """Pass :code:`True` if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)"""
     can_change_info: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can change chat title, photo and other settings"""
+    """Pass :code:`True` if the administrator can change chat title, photo and other settings"""
     can_invite_users: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can invite new users to the chat"""
+    """Pass :code:`True` if the administrator can invite new users to the chat"""
     can_pin_messages: Optional[bool] = None
-    """Pass :code:`True`, if the administrator can pin messages, supergroups only"""
+    """Pass :code:`True` if the administrator can pin messages, supergroups only"""
 
     def build_request(self, bot: Bot) -> Request:
         data: Dict[str, Any] = self.dict()
diff --git a/aiogram/methods/send_animation.py b/aiogram/methods/send_animation.py
index 78801a1e..6c59bf27 100644
--- a/aiogram/methods/send_animation.py
+++ b/aiogram/methods/send_animation.py
@@ -52,7 +52,7 @@ class SendAnimation(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_audio.py b/aiogram/methods/send_audio.py
index 4e31ed92..2a687ac2 100644
--- a/aiogram/methods/send_audio.py
+++ b/aiogram/methods/send_audio.py
@@ -53,7 +53,7 @@ class SendAudio(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_contact.py b/aiogram/methods/send_contact.py
index d0cb4ccb..fafe8177 100644
--- a/aiogram/methods/send_contact.py
+++ b/aiogram/methods/send_contact.py
@@ -41,7 +41,7 @@ class SendContact(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_dice.py b/aiogram/methods/send_dice.py
index dd844534..e6ed3004 100644
--- a/aiogram/methods/send_dice.py
+++ b/aiogram/methods/send_dice.py
@@ -35,7 +35,7 @@ class SendDice(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_document.py b/aiogram/methods/send_document.py
index a2de750d..b8ced8b1 100644
--- a/aiogram/methods/send_document.py
+++ b/aiogram/methods/send_document.py
@@ -48,7 +48,7 @@ class SendDocument(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_game.py b/aiogram/methods/send_game.py
index 416cd919..9f538e67 100644
--- a/aiogram/methods/send_game.py
+++ b/aiogram/methods/send_game.py
@@ -29,7 +29,7 @@ class SendGame(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[InlineKeyboardMarkup] = None
     """A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_. If empty, one 'Play game_title' button will be shown. If not empty, the first button must launch the game."""
 
diff --git a/aiogram/methods/send_invoice.py b/aiogram/methods/send_invoice.py
index 0e882699..d5b113a9 100644
--- a/aiogram/methods/send_invoice.py
+++ b/aiogram/methods/send_invoice.py
@@ -49,19 +49,19 @@ class SendInvoice(TelegramMethod[Message]):
     photo_height: Optional[int] = None
     """Photo height"""
     need_name: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's full name to complete the order"""
+    """Pass :code:`True` if you require the user's full name to complete the order"""
     need_phone_number: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's phone number to complete the order"""
+    """Pass :code:`True` if you require the user's phone number to complete the order"""
     need_email: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's email address to complete the order"""
+    """Pass :code:`True` if you require the user's email address to complete the order"""
     need_shipping_address: Optional[bool] = None
-    """Pass :code:`True`, if you require the user's shipping address to complete the order"""
+    """Pass :code:`True` if you require the user's shipping address to complete the order"""
     send_phone_number_to_provider: Optional[bool] = None
-    """Pass :code:`True`, if the user's phone number should be sent to provider"""
+    """Pass :code:`True` if the user's phone number should be sent to provider"""
     send_email_to_provider: Optional[bool] = None
-    """Pass :code:`True`, if the user's email address should be sent to provider"""
+    """Pass :code:`True` if the user's email address should be sent to provider"""
     is_flexible: Optional[bool] = None
-    """Pass :code:`True`, if the final price depends on the shipping method"""
+    """Pass :code:`True` if the final price depends on the shipping method"""
     disable_notification: Optional[bool] = None
     """Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound."""
     protect_content: Optional[bool] = None
@@ -69,7 +69,7 @@ class SendInvoice(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[InlineKeyboardMarkup] = None
     """A JSON-serialized object for an `inline keyboard <https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating>`_. If empty, one 'Pay :code:`total price`' button will be shown. If not empty, the first button must be a Pay button."""
 
diff --git a/aiogram/methods/send_location.py b/aiogram/methods/send_location.py
index 225f23eb..114f9020 100644
--- a/aiogram/methods/send_location.py
+++ b/aiogram/methods/send_location.py
@@ -45,7 +45,7 @@ class SendLocation(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_media_group.py b/aiogram/methods/send_media_group.py
index 7d5b4502..316a25d4 100644
--- a/aiogram/methods/send_media_group.py
+++ b/aiogram/methods/send_media_group.py
@@ -36,7 +36,7 @@ class SendMediaGroup(TelegramMethod[List[Message]]):
     reply_to_message_id: Optional[int] = None
     """If the messages are a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
 
     def build_request(self, bot: Bot) -> Request:
         data: Dict[str, Any] = self.dict()
diff --git a/aiogram/methods/send_message.py b/aiogram/methods/send_message.py
index d0269317..95d1d48e 100644
--- a/aiogram/methods/send_message.py
+++ b/aiogram/methods/send_message.py
@@ -43,7 +43,7 @@ class SendMessage(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_photo.py b/aiogram/methods/send_photo.py
index a4bb3d03..6c50c8c6 100644
--- a/aiogram/methods/send_photo.py
+++ b/aiogram/methods/send_photo.py
@@ -44,7 +44,7 @@ class SendPhoto(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_poll.py b/aiogram/methods/send_poll.py
index 85455b0d..30ae17b3 100644
--- a/aiogram/methods/send_poll.py
+++ b/aiogram/methods/send_poll.py
@@ -52,7 +52,7 @@ class SendPoll(TelegramMethod[Message]):
     close_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
     """Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with *open_period*."""
     is_closed: Optional[bool] = None
-    """Pass :code:`True`, if the poll needs to be immediately closed. This can be useful for poll preview."""
+    """Pass :code:`True` if the poll needs to be immediately closed. This can be useful for poll preview."""
     disable_notification: Optional[bool] = None
     """Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound."""
     protect_content: Optional[bool] = None
@@ -60,7 +60,7 @@ class SendPoll(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_sticker.py b/aiogram/methods/send_sticker.py
index 964f3e20..7cb1bc96 100644
--- a/aiogram/methods/send_sticker.py
+++ b/aiogram/methods/send_sticker.py
@@ -36,7 +36,7 @@ class SendSticker(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_venue.py b/aiogram/methods/send_venue.py
index df708ff8..9b0a06e8 100644
--- a/aiogram/methods/send_venue.py
+++ b/aiogram/methods/send_venue.py
@@ -49,7 +49,7 @@ class SendVenue(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_video.py b/aiogram/methods/send_video.py
index a41dbfe9..02496abe 100644
--- a/aiogram/methods/send_video.py
+++ b/aiogram/methods/send_video.py
@@ -46,7 +46,7 @@ class SendVideo(TelegramMethod[Message]):
     caption_entities: Optional[List[MessageEntity]] = None
     """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*"""
     supports_streaming: Optional[bool] = None
-    """Pass :code:`True`, if the uploaded video is suitable for streaming"""
+    """Pass :code:`True` if the uploaded video is suitable for streaming"""
     disable_notification: Optional[bool] = None
     """Sends the message `silently <https://telegram.org/blog/channels-2-0#silent-messages>`_. Users will receive a notification with no sound."""
     protect_content: Optional[bool] = None
@@ -54,7 +54,7 @@ class SendVideo(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_video_note.py b/aiogram/methods/send_video_note.py
index d26557b7..e20960cf 100644
--- a/aiogram/methods/send_video_note.py
+++ b/aiogram/methods/send_video_note.py
@@ -42,7 +42,7 @@ class SendVideoNote(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/send_voice.py b/aiogram/methods/send_voice.py
index afa9f75f..0cc1d602 100644
--- a/aiogram/methods/send_voice.py
+++ b/aiogram/methods/send_voice.py
@@ -46,7 +46,7 @@ class SendVoice(TelegramMethod[Message]):
     reply_to_message_id: Optional[int] = None
     """If the message is a reply, ID of the original message"""
     allow_sending_without_reply: Optional[bool] = None
-    """Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found"""
+    """Pass :code:`True` if the message should be sent even if the specified replied-to message is not found"""
     reply_markup: Optional[
         Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
     ] = None
diff --git a/aiogram/methods/set_game_score.py b/aiogram/methods/set_game_score.py
index f1fe949b..c3f8ce92 100644
--- a/aiogram/methods/set_game_score.py
+++ b/aiogram/methods/set_game_score.py
@@ -23,9 +23,9 @@ class SetGameScore(TelegramMethod[Union[Message, bool]]):
     score: int
     """New score, must be non-negative"""
     force: Optional[bool] = None
-    """Pass :code:`True`, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters"""
+    """Pass :code:`True` if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters"""
     disable_edit_message: Optional[bool] = None
-    """Pass :code:`True`, if the game message should not be automatically edited to include the current scoreboard"""
+    """Pass :code:`True` if the game message should not be automatically edited to include the current scoreboard"""
     chat_id: Optional[int] = None
     """Required if *inline_message_id* is not specified. Unique identifier for the target chat"""
     message_id: Optional[int] = None
diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py
index e4a1819b..739882cf 100644
--- a/aiogram/types/__init__.py
+++ b/aiogram/types/__init__.py
@@ -1,3 +1,5 @@
+from typing import Optional
+
 from .animation import Animation
 from .audio import Audio
 from .base import UNSET, TelegramObject
@@ -284,7 +286,10 @@ for _entity_name in __all__:
     _entity = globals()[_entity_name]
     if not hasattr(_entity, "update_forward_refs"):
         continue
-    _entity.update_forward_refs(**globals())
+    _entity.update_forward_refs(
+        **{k: v for k, v in globals().items() if k in __all__},
+        **{"Optional": Optional},
+    )
 
 del _entity
 del _entity_name
diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py
index 95d0ed7c..875ef36c 100644
--- a/aiogram/types/chat.py
+++ b/aiogram/types/chat.py
@@ -37,6 +37,8 @@ class Chat(TelegramObject):
     """*Optional*. Bio of the other party in a private chat. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
     has_private_forwards: Optional[bool] = None
     """*Optional*. :code:`True`, if privacy settings of the other party in the private chat allows to use :code:`tg://user?id=<user_id>` links only in chats with the user. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
+    has_restricted_voice_and_video_messages: Optional[bool] = None
+    """*Optional*. :code:`True`, if the privacy settings of the other party restrict sending voice and video note messages in the private chat. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
     join_to_send_messages: Optional[bool] = None
     """*Optional*. :code:`True`, if users need to join the supergroup before they can send messages. Returned only in :class:`aiogram.methods.get_chat.GetChat`."""
     join_by_request: Optional[bool] = None
diff --git a/aiogram/types/inline_query_result_article.py b/aiogram/types/inline_query_result_article.py
index 27164254..9fa6a9c6 100644
--- a/aiogram/types/inline_query_result_article.py
+++ b/aiogram/types/inline_query_result_article.py
@@ -31,7 +31,7 @@ class InlineQueryResultArticle(InlineQueryResult):
     url: Optional[str] = None
     """*Optional*. URL of the result"""
     hide_url: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if you don't want the URL to be shown in the message"""
+    """*Optional*. Pass :code:`True` if you don't want the URL to be shown in the message"""
     description: Optional[str] = None
     """*Optional*. Short description of the result"""
     thumb_url: Optional[str] = None
diff --git a/aiogram/types/input_invoice_message_content.py b/aiogram/types/input_invoice_message_content.py
index 8636cf07..4af5596d 100644
--- a/aiogram/types/input_invoice_message_content.py
+++ b/aiogram/types/input_invoice_message_content.py
@@ -42,16 +42,16 @@ class InputInvoiceMessageContent(InputMessageContent):
     photo_height: Optional[int] = None
     """*Optional*. Photo height"""
     need_name: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if you require the user's full name to complete the order"""
+    """*Optional*. Pass :code:`True` if you require the user's full name to complete the order"""
     need_phone_number: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if you require the user's phone number to complete the order"""
+    """*Optional*. Pass :code:`True` if you require the user's phone number to complete the order"""
     need_email: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if you require the user's email address to complete the order"""
+    """*Optional*. Pass :code:`True` if you require the user's email address to complete the order"""
     need_shipping_address: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if you require the user's shipping address to complete the order"""
+    """*Optional*. Pass :code:`True` if you require the user's shipping address to complete the order"""
     send_phone_number_to_provider: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if the user's phone number should be sent to provider"""
+    """*Optional*. Pass :code:`True` if the user's phone number should be sent to provider"""
     send_email_to_provider: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if the user's email address should be sent to provider"""
+    """*Optional*. Pass :code:`True` if the user's email address should be sent to provider"""
     is_flexible: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if the final price depends on the shipping method"""
+    """*Optional*. Pass :code:`True` if the final price depends on the shipping method"""
diff --git a/aiogram/types/input_media_video.py b/aiogram/types/input_media_video.py
index 72149b84..224663e3 100644
--- a/aiogram/types/input_media_video.py
+++ b/aiogram/types/input_media_video.py
@@ -38,4 +38,4 @@ class InputMediaVideo(InputMedia):
     duration: Optional[int] = None
     """*Optional*. Video duration in seconds"""
     supports_streaming: Optional[bool] = None
-    """*Optional*. Pass :code:`True`, if the uploaded video is suitable for streaming"""
+    """*Optional*. Pass :code:`True` if the uploaded video is suitable for streaming"""
diff --git a/aiogram/types/keyboard_button.py b/aiogram/types/keyboard_button.py
index 40c70420..b69e9287 100644
--- a/aiogram/types/keyboard_button.py
+++ b/aiogram/types/keyboard_button.py
@@ -9,10 +9,6 @@ if TYPE_CHECKING:
     from .web_app_info import WebAppInfo
 
 
-class WebApp(MutableTelegramObject):
-    url: str
-
-
 class KeyboardButton(MutableTelegramObject):
     """
     This object represents one button of the reply keyboard. For simple text buttons *String* can be used instead of this object to specify text of the button. Optional fields *web_app*, *request_contact*, *request_location*, and *request_poll* are mutually exclusive.
diff --git a/aiogram/types/login_url.py b/aiogram/types/login_url.py
index f367845e..95a66eac 100644
--- a/aiogram/types/login_url.py
+++ b/aiogram/types/login_url.py
@@ -16,7 +16,7 @@ class LoginUrl(TelegramObject):
     """
 
     url: str
-    """An HTTP URL to be opened with user authorization data added to the query string when the button is pressed. If the user refuses to provide authorization data, the original URL without information about the user will be opened. The data added is the same as described in `Receiving authorization data <https://core.telegram.org/widgets/login#receiving-authorization-data>`_."""
+    """An HTTPS URL to be opened with user authorization data added to the query string when the button is pressed. If the user refuses to provide authorization data, the original URL without information about the user will be opened. The data added is the same as described in `Receiving authorization data <https://core.telegram.org/widgets/login#receiving-authorization-data>`_."""
     forward_text: Optional[str] = None
     """*Optional*. New text of the button in forwarded messages."""
     bot_username: Optional[str] = None
diff --git a/aiogram/types/menu_button.py b/aiogram/types/menu_button.py
index 0a709dd6..37707302 100644
--- a/aiogram/types/menu_button.py
+++ b/aiogram/types/menu_button.py
@@ -1,11 +1,11 @@
 from __future__ import annotations
 
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Optional
 
 from .base import TelegramObject
 
 if TYPE_CHECKING:
-    pass
+    from .web_app_info import WebAppInfo
 
 
 class MenuButton(TelegramObject):
@@ -20,3 +20,10 @@ class MenuButton(TelegramObject):
 
     Source: https://core.telegram.org/bots/api#menubutton
     """
+
+    type: str
+    """..."""
+    text: Optional[str] = None
+    """*Optional*. Text on the button"""
+    web_app: Optional[WebAppInfo] = None
+    """*Optional*. Description of the Web App that will be launched when the user presses the button. The Web App will be able to send an arbitrary message on behalf of the user using the method :class:`aiogram.methods.answer_web_app_query.AnswerWebAppQuery`."""
diff --git a/aiogram/types/message_entity.py b/aiogram/types/message_entity.py
index fa6aea41..875434f7 100644
--- a/aiogram/types/message_entity.py
+++ b/aiogram/types/message_entity.py
@@ -18,7 +18,7 @@ class MessageEntity(MutableTelegramObject):
     """
 
     type: str
-    """Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag`), 'cashtag' (:code:`$USD`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames <https://telegram.org/blog/edit#new-mentions>`_)"""
+    """Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag`), 'cashtag' (:code:`$USD`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames <https://telegram.org/blog/edit#new-mentions>`_), 'custom_emoji' (for inline custom emoji stickers)"""
     offset: int
     """Offset in UTF-16 code units to the start of the entity"""
     length: int
@@ -29,6 +29,8 @@ class MessageEntity(MutableTelegramObject):
     """*Optional*. For 'text_mention' only, the mentioned user"""
     language: Optional[str] = None
     """*Optional*. For 'pre' only, the programming language of the entity text"""
+    custom_emoji_id: Optional[str] = None
+    """*Optional*. For 'custom_emoji' only, unique identifier of the custom emoji. Use :class:`aiogram.methods.get_custom_emoji_stickers.GetCustomEmojiStickers` to get full information about the sticker"""
 
     def extract_from(self, text: str) -> str:
         return remove_surrogates(
diff --git a/aiogram/types/sticker.py b/aiogram/types/sticker.py
index d10844f2..19f01a02 100644
--- a/aiogram/types/sticker.py
+++ b/aiogram/types/sticker.py
@@ -21,6 +21,8 @@ class Sticker(TelegramObject):
     """Identifier for this file, which can be used to download or reuse the file"""
     file_unique_id: str
     """Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file."""
+    type: str
+    """Type of the sticker, currently one of 'regular', 'mask', 'custom_emoji'. The type of the sticker is independent from its format, which is determined by the fields *is_animated* and *is_video*."""
     width: int
     """Sticker width"""
     height: int
@@ -36,8 +38,10 @@ class Sticker(TelegramObject):
     set_name: Optional[str] = None
     """*Optional*. Name of the sticker set to which the sticker belongs"""
     premium_animation: Optional[File] = None
-    """*Optional*. Premium animation for the sticker, if the sticker is premium"""
+    """*Optional*. For premium regular stickers, premium animation for the sticker"""
     mask_position: Optional[MaskPosition] = None
     """*Optional*. For mask stickers, the position where the mask should be placed"""
+    custom_emoji_id: Optional[str] = None
+    """*Optional*. For custom emoji stickers, unique identifier of the custom emoji"""
     file_size: Optional[int] = None
     """*Optional*. File size in bytes"""
diff --git a/aiogram/types/sticker_set.py b/aiogram/types/sticker_set.py
index 3ed5055c..8f2b264e 100644
--- a/aiogram/types/sticker_set.py
+++ b/aiogram/types/sticker_set.py
@@ -20,12 +20,12 @@ class StickerSet(TelegramObject):
     """Sticker set name"""
     title: str
     """Sticker set title"""
+    sticker_type: str
+    """Type of stickers in the set, currently one of 'regular', 'mask', 'custom_emoji'"""
     is_animated: bool
     """:code:`True`, if the sticker set contains `animated stickers <https://telegram.org/blog/animated-stickers>`_"""
     is_video: bool
     """:code:`True`, if the sticker set contains `video stickers <https://telegram.org/blog/video-stickers-better-reactions>`_"""
-    contains_masks: bool
-    """:code:`True`, if the sticker set contains masks"""
     stickers: List[Sticker]
     """List of all set stickers"""
     thumb: Optional[PhotoSize] = None
diff --git a/aiogram/utils/text_decorations.py b/aiogram/utils/text_decorations.py
index 63f82d60..36e41219 100644
--- a/aiogram/utils/text_decorations.py
+++ b/aiogram/utils/text_decorations.py
@@ -54,6 +54,8 @@ class TextDecoration(ABC):
             return self.link(value=text, link=f"tg://user?id={user.id}")
         if entity.type == "text_link":
             return self.link(value=text, link=cast(str, entity.url))
+        if entity.type == "custom_emoji":
+            return self.custom_emoji(value=text, custom_emoji_id=cast(str, entity.custom_emoji_id))
 
         return self.quote(text)
 
@@ -140,7 +142,11 @@ class TextDecoration(ABC):
         pass
 
     @abstractmethod
-    def quote(self, value: str) -> str:  # pragma: no cover
+    def quote(self, value: str) -> str:
+        pass
+
+    @abstractmethod
+    def custom_emoji(self, value: str, custom_emoji_id: str) -> str:
         pass
 
 
@@ -149,7 +155,8 @@ class HtmlDecoration(TextDecoration):
     ITALIC_TAG = "i"
     UNDERLINE_TAG = "u"
     STRIKETHROUGH_TAG = "s"
-    SPOILER_TAG = ('span class="tg-spoiler"', "span")
+    SPOILER_TAG = "tg-spoiler"
+    EMOJI_TAG = "tg-emoji"
 
     def link(self, value: str, link: str) -> str:
         return f'<a href="{link}">{value}</a>'
@@ -176,11 +183,14 @@ class HtmlDecoration(TextDecoration):
         return f"<{self.STRIKETHROUGH_TAG}>{value}</{self.STRIKETHROUGH_TAG}>"
 
     def spoiler(self, value: str) -> str:
-        return f"<{self.SPOILER_TAG[0]}>{value}</{self.SPOILER_TAG[1]}>"
+        return f"<{self.SPOILER_TAG}>{value}</{self.SPOILER_TAG}>"
 
     def quote(self, value: str) -> str:
         return html.escape(value, quote=False)
 
+    def custom_emoji(self, value: str, custom_emoji_id: str) -> str:
+        return f'<{self.EMOJI_TAG} emoji-id="{custom_emoji_id}">{value}</tg-emoji>'
+
 
 class MarkdownDecoration(TextDecoration):
     MARKDOWN_QUOTE_PATTERN: Pattern[str] = re.compile(r"([_*\[\]()~`>#+\-=|{}.!\\])")
@@ -215,6 +225,9 @@ class MarkdownDecoration(TextDecoration):
     def quote(self, value: str) -> str:
         return re.sub(pattern=self.MARKDOWN_QUOTE_PATTERN, repl=r"\\\1", string=value)
 
+    def custom_emoji(self, value: str, custom_emoji_id: str) -> str:
+        return self.link(value=value, link=f"tg://emoji?id={custom_emoji_id}")
+
 
 html_decoration = HtmlDecoration()
 markdown_decoration = MarkdownDecoration()
diff --git a/docs/api/methods/get_custom_emoji_stickers.rst b/docs/api/methods/get_custom_emoji_stickers.rst
new file mode 100644
index 00000000..9c7455fd
--- /dev/null
+++ b/docs/api/methods/get_custom_emoji_stickers.rst
@@ -0,0 +1,37 @@
+######################
+getCustomEmojiStickers
+######################
+
+Returns: :obj:`List[Sticker]`
+
+.. automodule:: aiogram.methods.get_custom_emoji_stickers
+    :members:
+    :member-order: bysource
+    :undoc-members: True
+
+
+Usage
+=====
+
+As bot method
+-------------
+
+.. code-block::
+
+    result: List[Sticker] = await bot.get_custom_emoji_stickers(...)
+
+
+Method as object
+----------------
+
+Imports:
+
+- :code:`from aiogram.methods.get_custom_emoji_stickers import GetCustomEmojiStickers`
+- alias: :code:`from aiogram.methods import GetCustomEmojiStickers`
+
+With specific bot
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+    result: List[Sticker] = await bot(GetCustomEmojiStickers(...))
diff --git a/docs/api/methods/index.rst b/docs/api/methods/index.rst
index 0fa45e7c..d09d5881 100644
--- a/docs/api/methods/index.rst
+++ b/docs/api/methods/index.rst
@@ -108,6 +108,7 @@ Stickers
 
     send_sticker
     get_sticker_set
+    get_custom_emoji_stickers
     upload_sticker_file
     create_new_sticker_set
     add_sticker_to_set
diff --git a/docs/api/methods/send_chat_action.rst b/docs/api/methods/send_chat_action.rst
index 97d3bd22..7a3100bd 100644
--- a/docs/api/methods/send_chat_action.rst
+++ b/docs/api/methods/send_chat_action.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.send_chat_action import SendChatAction`
 - alias: :code:`from aiogram.methods import SendChatAction`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SendChatAction(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_chat_sticker_set.rst b/docs/api/methods/set_chat_sticker_set.rst
index 71e447b2..a7cfcea1 100644
--- a/docs/api/methods/set_chat_sticker_set.rst
+++ b/docs/api/methods/set_chat_sticker_set.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_chat_sticker_set import SetChatStickerSet`
 - alias: :code:`from aiogram.methods import SetChatStickerSet`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetChatStickerSet(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_chat_title.rst b/docs/api/methods/set_chat_title.rst
index b9473be9..739b817d 100644
--- a/docs/api/methods/set_chat_title.rst
+++ b/docs/api/methods/set_chat_title.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_chat_title import SetChatTitle`
 - alias: :code:`from aiogram.methods import SetChatTitle`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetChatTitle(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_game_score.rst b/docs/api/methods/set_game_score.rst
index de9dd9b3..ef484655 100644
--- a/docs/api/methods/set_game_score.rst
+++ b/docs/api/methods/set_game_score.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_game_score import SetGameScore`
 - alias: :code:`from aiogram.methods import SetGameScore`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: Union[Message, bool] = await SetGameScore(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_my_commands.rst b/docs/api/methods/set_my_commands.rst
index 456bf270..191f30e1 100644
--- a/docs/api/methods/set_my_commands.rst
+++ b/docs/api/methods/set_my_commands.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_my_commands import SetMyCommands`
 - alias: :code:`from aiogram.methods import SetMyCommands`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetMyCommands(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_my_default_administrator_rights.rst b/docs/api/methods/set_my_default_administrator_rights.rst
index c115568c..1caabdfd 100644
--- a/docs/api/methods/set_my_default_administrator_rights.rst
+++ b/docs/api/methods/set_my_default_administrator_rights.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_my_default_administrator_rights import SetMyDefaultAdministratorRights`
 - alias: :code:`from aiogram.methods import SetMyDefaultAdministratorRights`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetMyDefaultAdministratorRights(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_passport_data_errors.rst b/docs/api/methods/set_passport_data_errors.rst
index 8db5be3c..ac49f78c 100644
--- a/docs/api/methods/set_passport_data_errors.rst
+++ b/docs/api/methods/set_passport_data_errors.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_passport_data_errors import SetPassportDataErrors`
 - alias: :code:`from aiogram.methods import SetPassportDataErrors`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetPassportDataErrors(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_sticker_position_in_set.rst b/docs/api/methods/set_sticker_position_in_set.rst
index f0b4771b..168dbe9c 100644
--- a/docs/api/methods/set_sticker_position_in_set.rst
+++ b/docs/api/methods/set_sticker_position_in_set.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_sticker_position_in_set import SetStickerPositionInSet`
 - alias: :code:`from aiogram.methods import SetStickerPositionInSet`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetStickerPositionInSet(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_sticker_set_thumb.rst b/docs/api/methods/set_sticker_set_thumb.rst
index fb4a85e6..133fad94 100644
--- a/docs/api/methods/set_sticker_set_thumb.rst
+++ b/docs/api/methods/set_sticker_set_thumb.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_sticker_set_thumb import SetStickerSetThumb`
 - alias: :code:`from aiogram.methods import SetStickerSetThumb`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetStickerSetThumb(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/set_webhook.rst b/docs/api/methods/set_webhook.rst
index 5e0a6e20..8e7d78d5 100644
--- a/docs/api/methods/set_webhook.rst
+++ b/docs/api/methods/set_webhook.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.set_webhook import SetWebhook`
 - alias: :code:`from aiogram.methods import SetWebhook`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await SetWebhook(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/stop_message_live_location.rst b/docs/api/methods/stop_message_live_location.rst
index f7519860..1ef6440a 100644
--- a/docs/api/methods/stop_message_live_location.rst
+++ b/docs/api/methods/stop_message_live_location.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.stop_message_live_location import StopMessageLiveLocation`
 - alias: :code:`from aiogram.methods import StopMessageLiveLocation`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: Union[Message, bool] = await StopMessageLiveLocation(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/stop_poll.rst b/docs/api/methods/stop_poll.rst
index 2e14c094..c51afc90 100644
--- a/docs/api/methods/stop_poll.rst
+++ b/docs/api/methods/stop_poll.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.stop_poll import StopPoll`
 - alias: :code:`from aiogram.methods import StopPoll`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: Poll = await StopPoll(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/unban_chat_member.rst b/docs/api/methods/unban_chat_member.rst
index 6aae1669..fef8e7fe 100644
--- a/docs/api/methods/unban_chat_member.rst
+++ b/docs/api/methods/unban_chat_member.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.unban_chat_member import UnbanChatMember`
 - alias: :code:`from aiogram.methods import UnbanChatMember`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await UnbanChatMember(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/unban_chat_sender_chat.rst b/docs/api/methods/unban_chat_sender_chat.rst
index f0f929da..c694503b 100644
--- a/docs/api/methods/unban_chat_sender_chat.rst
+++ b/docs/api/methods/unban_chat_sender_chat.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.unban_chat_sender_chat import UnbanChatSenderChat`
 - alias: :code:`from aiogram.methods import UnbanChatSenderChat`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await UnbanChatSenderChat(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/unpin_all_chat_messages.rst b/docs/api/methods/unpin_all_chat_messages.rst
index 90c2ca9e..4421245e 100644
--- a/docs/api/methods/unpin_all_chat_messages.rst
+++ b/docs/api/methods/unpin_all_chat_messages.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.unpin_all_chat_messages import UnpinAllChatMessages`
 - alias: :code:`from aiogram.methods import UnpinAllChatMessages`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await UnpinAllChatMessages(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/unpin_chat_message.rst b/docs/api/methods/unpin_chat_message.rst
index 02c6e816..1531ec19 100644
--- a/docs/api/methods/unpin_chat_message.rst
+++ b/docs/api/methods/unpin_chat_message.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.unpin_chat_message import UnpinChatMessage`
 - alias: :code:`from aiogram.methods import UnpinChatMessage`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: bool = await UnpinChatMessage(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/docs/api/methods/upload_sticker_file.rst b/docs/api/methods/upload_sticker_file.rst
index 210c9784..c542515d 100644
--- a/docs/api/methods/upload_sticker_file.rst
+++ b/docs/api/methods/upload_sticker_file.rst
@@ -29,13 +29,6 @@ Imports:
 - :code:`from aiogram.methods.upload_sticker_file import UploadStickerFile`
 - alias: :code:`from aiogram.methods import UploadStickerFile`
 
-In handlers with current bot
-----------------------------
-
-.. code-block:: python
-
-    result: File = await UploadStickerFile(...)
-
 With specific bot
 ~~~~~~~~~~~~~~~~~
 
diff --git a/poetry.lock b/poetry.lock
index 5f04b1ce..184a94b0 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -60,7 +60,7 @@ python-versions = "*"
 
 [[package]]
 name = "aresponses"
-version = "2.1.5"
+version = "2.1.6"
 description = "Asyncio response mocking. Similar to the responses library used for 'requests'"
 category = "dev"
 optional = false
@@ -131,12 +131,12 @@ python-versions = ">=3.6.0"
 soupsieve = ">1.2"
 
 [package.extras]
-html5lib = ["html5lib"]
 lxml = ["lxml"]
+html5lib = ["html5lib"]
 
 [[package]]
 name = "black"
-version = "22.3.0"
+version = "22.6.0"
 description = "The uncompromising code formatter."
 category = "dev"
 optional = false
@@ -147,7 +147,7 @@ click = ">=8.0.0"
 mypy-extensions = ">=0.4.3"
 pathspec = ">=0.9.0"
 platformdirs = ">=2"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
 typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
 
 [package.extras]
@@ -207,7 +207,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "coverage"
-version = "6.4.1"
+version = "6.4.3"
 description = "Code coverage measurement for Python"
 category = "dev"
 optional = false
@@ -263,16 +263,16 @@ testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-co
 
 [[package]]
 name = "flake8"
-version = "4.0.1"
+version = "5.0.4"
 description = "the modular source code checker: pep8 pyflakes and co"
 category = "dev"
 optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.6.1"
 
 [package.dependencies]
-mccabe = ">=0.6.0,<0.7.0"
-pycodestyle = ">=2.8.0,<2.9.0"
-pyflakes = ">=2.4.0,<2.5.0"
+mccabe = ">=0.7.0,<0.8.0"
+pycodestyle = ">=2.9.0,<2.10.0"
+pyflakes = ">=2.5.0,<2.6.0"
 
 [[package]]
 name = "frozenlist"
@@ -348,7 +348,7 @@ optional = true
 python-versions = "*"
 
 [package.extras]
-scripts = ["click (>=6.0)", "twisted (>=16.4.0)"]
+scripts = ["twisted (>=16.4.0)", "click (>=6.0)"]
 
 [[package]]
 name = "iniconfig"
@@ -400,7 +400,7 @@ tornado = {version = "*", markers = "python_version > \"2.7\""}
 
 [[package]]
 name = "magic-filter"
-version = "1.0.7"
+version = "1.0.8"
 description = "This package provides magic filter based on dynamic attribute getter"
 category = "main"
 optional = false
@@ -418,18 +418,18 @@ python-versions = ">=3.6"
 importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
 
 [package.extras]
-testing = ["coverage", "pyyaml"]
+testing = ["pyyaml", "coverage"]
 
 [[package]]
 name = "markdown-include"
-version = "0.6.0"
+version = "0.7.0"
 description = "This is an extension to Python-Markdown which provides an \"include\" function, similar to that found in LaTeX (and also the C pre-processor and Fortran). I originally wrote it for my FORD Fortran auto-documentation generator."
 category = "main"
 optional = true
 python-versions = "*"
 
 [package.dependencies]
-markdown = "*"
+markdown = ">=3.0"
 
 [[package]]
 name = "markupsafe"
@@ -441,11 +441,11 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "mccabe"
-version = "0.6.1"
+version = "0.7.0"
 description = "McCabe checker, plugin for flake8"
 category = "dev"
 optional = false
-python-versions = "*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "multidict"
@@ -457,7 +457,7 @@ python-versions = ">=3.7"
 
 [[package]]
 name = "mypy"
-version = "0.961"
+version = "0.971"
 description = "Optional static typing for Python"
 category = "dev"
 optional = false
@@ -469,9 +469,9 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
 typing-extensions = ">=3.10"
 
 [package.extras]
-dmypy = ["psutil (>=4.0)"]
-python2 = ["typed-ast (>=1.4.0,<2)"]
 reports = ["lxml"]
+python2 = ["typed-ast (>=1.4.0,<2)"]
+dmypy = ["psutil (>=4.0)"]
 
 [[package]]
 name = "mypy-extensions"
@@ -534,7 +534,7 @@ testing = ["pytest", "pytest-benchmark"]
 
 [[package]]
 name = "pre-commit"
-version = "2.19.0"
+version = "2.20.0"
 description = "A framework for managing and maintaining multi-language pre-commit hooks."
 category = "dev"
 optional = false
@@ -558,15 +558,15 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
 [[package]]
 name = "pycodestyle"
-version = "2.8.0"
+version = "2.9.1"
 description = "Python style guide checker"
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "pydantic"
-version = "1.9.1"
+version = "1.9.2"
 description = "Data validation and settings management using python type hints"
 category = "main"
 optional = false
@@ -576,16 +576,16 @@ python-versions = ">=3.6.1"
 typing-extensions = ">=3.7.4.3"
 
 [package.extras]
-dotenv = ["python-dotenv (>=0.10.4)"]
 email = ["email-validator (>=1.0.3)"]
+dotenv = ["python-dotenv (>=0.10.4)"]
 
 [[package]]
 name = "pyflakes"
-version = "2.4.0"
+version = "2.5.0"
 description = "passive checker of Python programs"
 category = "dev"
 optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
 
 [[package]]
 name = "pygments"
@@ -652,11 +652,11 @@ pytest = ">=6.1.0"
 pytest-asyncio = ">=0.17.2"
 
 [package.extras]
-testing = ["coverage (==6.2)", "mypy (==0.931)"]
+testing = ["mypy (==0.931)", "coverage (==6.2)"]
 
 [[package]]
 name = "pytest-asyncio"
-version = "0.18.3"
+version = "0.19.0"
 description = "Pytest support for asyncio"
 category = "dev"
 optional = false
@@ -666,7 +666,7 @@ python-versions = ">=3.7"
 pytest = ">=6.1.0"
 
 [package.extras]
-testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (==0.931)", "pytest-trio (>=0.7.0)"]
+testing = ["pytest-trio (>=0.7.0)", "mypy (>=0.931)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "coverage (>=6.2)"]
 
 [[package]]
 name = "pytest-cov"
@@ -719,7 +719,7 @@ pytest = ">=7.1.1,<8.0.0"
 
 [[package]]
 name = "pytest-mock"
-version = "3.8.1"
+version = "3.8.2"
 description = "Thin-wrapper around the mock package for easier use with pytest"
 category = "dev"
 optional = false
@@ -729,7 +729,7 @@ python-versions = ">=3.7"
 pytest = ">=5.0"
 
 [package.extras]
-dev = ["pre-commit", "tox", "pytest-asyncio"]
+dev = ["pytest-asyncio", "tox", "pre-commit"]
 
 [[package]]
 name = "pytest-mypy"
@@ -743,12 +743,12 @@ python-versions = ">=3.5"
 attrs = ">=19.0"
 filelock = ">=3.0"
 mypy = [
-    {version = ">=0.700", markers = "python_version >= \"3.8\" and python_version < \"3.9\""},
     {version = ">=0.780", markers = "python_version >= \"3.9\""},
+    {version = ">=0.700", markers = "python_version >= \"3.8\" and python_version < \"3.9\""},
 ]
 pytest = [
-    {version = ">=6.2", markers = "python_version >= \"3.10\""},
     {version = ">=4.6", markers = "python_version >= \"3.6\" and python_version < \"3.10\""},
+    {version = ">=6.2", markers = "python_version >= \"3.10\""},
 ]
 
 [[package]]
@@ -763,10 +763,10 @@ python-versions = "*"
 async-timeout = {version = ">=3.0.1", optional = true, markers = "extra == \"asyncio\""}
 
 [package.extras]
-anyio = ["anyio (>=3.3.4)"]
-asyncio = ["async-timeout (>=3.0.1)"]
-curio = ["curio (>=1.4)"]
 trio = ["trio (>=0.16.0)"]
+curio = ["curio (>=1.4)"]
+asyncio = ["async-timeout (>=3.0.1)"]
+anyio = ["anyio (>=3.3.4)"]
 
 [[package]]
 name = "pytz"
@@ -786,7 +786,7 @@ python-versions = ">=3.6"
 
 [[package]]
 name = "redis"
-version = "4.3.3"
+version = "4.3.4"
 description = "Python client for Redis database and key-value store"
 category = "main"
 optional = true
@@ -865,9 +865,9 @@ sphinxcontrib-qthelp = "*"
 sphinxcontrib-serializinghtml = ">=1.1.5"
 
 [package.extras]
+test = ["typed-ast", "cython", "html5lib", "pytest-cov", "pytest"]
+lint = ["types-requests", "types-typed-ast", "docutils-stubs", "mypy (>=0.931)", "isort", "flake8 (>=3.5.0)"]
 docs = ["sphinxcontrib-websupport"]
-lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"]
-test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"]
 
 [[package]]
 name = "sphinx-autobuild"
@@ -883,7 +883,7 @@ livereload = "*"
 sphinx = "*"
 
 [package.extras]
-test = ["pytest", "pytest-cov"]
+test = ["pytest-cov", "pytest"]
 
 [[package]]
 name = "sphinx-basic-ng"
@@ -897,7 +897,7 @@ python-versions = ">=3.7"
 sphinx = ">=4.0,<6.0"
 
 [package.extras]
-docs = ["furo", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs", "ipython"]
+docs = ["ipython", "sphinx-inline-tabs", "sphinx-copybutton", "myst-parser", "furo"]
 
 [[package]]
 name = "sphinx-copybutton"
@@ -911,8 +911,8 @@ python-versions = ">=3.6"
 sphinx = ">=1.8"
 
 [package.extras]
+rtd = ["sphinx-book-theme", "myst-nb", "ipython", "sphinx"]
 code_style = ["pre-commit (==2.12.1)"]
-rtd = ["sphinx", "ipython", "myst-nb", "sphinx-book-theme"]
 
 [[package]]
 name = "sphinx-intl"
@@ -957,7 +957,7 @@ sphinx = ">=2.0.0"
 sphinx-prompt = ">=0.1"
 
 [package.extras]
-dev = ["autoflake (==1.4)", "black (==20.8b1)", "check-manifest (==0.43)", "doc8 (==0.8.1)", "flake8-commas (==2.0.0)", "flake8-quotes (==3.2.0)", "flake8 (==3.8.3)", "isort (==5.5.4)", "mypy (==0.782)", "pip-check-reqs (==2.1.1)", "pydocstyle (==5.1.1)", "pyenchant (==3.1.1)", "pygithub (==1.53)", "pylint (==2.6.0)", "pyroma (==2.6)", "pytest-cov (==2.10.1)", "pytest (==6.1.0)", "twine (==3.2.0)", "vulture (==2.1)"]
+dev = ["vulture (==2.1)", "twine (==3.2.0)", "pytest (==6.1.0)", "pytest-cov (==2.10.1)", "pyroma (==2.6)", "pylint (==2.6.0)", "pygithub (==1.53)", "pyenchant (==3.1.1)", "pydocstyle (==5.1.1)", "pip-check-reqs (==2.1.1)", "mypy (==0.782)", "isort (==5.5.4)", "flake8 (==3.8.3)", "flake8-quotes (==3.2.0)", "flake8-commas (==2.0.0)", "doc8 (==0.8.1)", "check-manifest (==0.43)", "black (==20.8b1)", "autoflake (==1.4)"]
 
 [[package]]
 name = "sphinxcontrib-applehelp"
@@ -968,8 +968,8 @@ optional = true
 python-versions = ">=3.5"
 
 [package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
 test = ["pytest"]
+lint = ["docutils-stubs", "mypy", "flake8"]
 
 [[package]]
 name = "sphinxcontrib-devhelp"
@@ -980,8 +980,8 @@ optional = true
 python-versions = ">=3.5"
 
 [package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
 test = ["pytest"]
+lint = ["docutils-stubs", "mypy", "flake8"]
 
 [[package]]
 name = "sphinxcontrib-htmlhelp"
@@ -992,8 +992,8 @@ optional = true
 python-versions = ">=3.6"
 
 [package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
-test = ["pytest", "html5lib"]
+test = ["html5lib", "pytest"]
+lint = ["docutils-stubs", "mypy", "flake8"]
 
 [[package]]
 name = "sphinxcontrib-jsmath"
@@ -1004,7 +1004,7 @@ optional = true
 python-versions = ">=3.5"
 
 [package.extras]
-test = ["pytest", "flake8", "mypy"]
+test = ["mypy", "flake8", "pytest"]
 
 [[package]]
 name = "sphinxcontrib-qthelp"
@@ -1015,8 +1015,8 @@ optional = true
 python-versions = ">=3.5"
 
 [package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
 test = ["pytest"]
+lint = ["docutils-stubs", "mypy", "flake8"]
 
 [[package]]
 name = "sphinxcontrib-serializinghtml"
@@ -1027,8 +1027,8 @@ optional = true
 python-versions = ">=3.5"
 
 [package.extras]
-lint = ["flake8", "mypy", "docutils-stubs"]
 test = ["pytest"]
+lint = ["docutils-stubs", "mypy", "flake8"]
 
 [[package]]
 name = "toml"
@@ -1074,7 +1074,7 @@ dev = ["packaging"]
 
 [[package]]
 name = "typing-extensions"
-version = "4.2.0"
+version = "4.3.0"
 description = "Backported and Experimental Type Hints for Python 3.7+"
 category = "main"
 optional = false
@@ -1108,8 +1108,8 @@ platformdirs = ">=2,<3"
 six = ">=1.9.0,<2"
 
 [package.extras]
-docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"]
-testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"]
+testing = ["packaging (>=20.0)", "pytest-timeout (>=1)", "pytest-randomly (>=1)", "pytest-mock (>=2)", "pytest-freezegun (>=0.4.1)", "pytest-env (>=0.6.2)", "pytest (>=4)", "flaky (>=3)", "coverage-enable-subprocess (>=1)", "coverage (>=4)"]
+docs = ["towncrier (>=21.3)", "sphinx-rtd-theme (>=0.4.3)", "sphinx-argparse (>=0.2.5)", "sphinx (>=3)", "proselint (>=0.10.2)"]
 
 [[package]]
 name = "wrapt"
@@ -1153,13 +1153,10 @@ redis = ["redis"]
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.8"
-content-hash = "f236269d4c2c6589474cb1bd028ef42ebbb424bc77062db6c16f0a5b6e542d4c"
+content-hash = "9ace8d411030e4e7eea717461331c7b39734187b25ceaf65a7c3d675d71df0d0"
 
 [metadata.files]
-aiofiles = [
-    {file = "aiofiles-0.8.0-py3-none-any.whl", hash = "sha256:7a973fc22b29e9962d0897805ace5856e6a566ab1f0c8e5c91ff6c866519c937"},
-    {file = "aiofiles-0.8.0.tar.gz", hash = "sha256:8334f23235248a3b2e83b2c3a78a22674f39969b96397126cc93664d9a901e59"},
-]
+aiofiles = []
 aiohttp = [
     {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8"},
     {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8"},
@@ -1234,30 +1231,18 @@ aiohttp = [
     {file = "aiohttp-3.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac"},
     {file = "aiohttp-3.8.1.tar.gz", hash = "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578"},
 ]
-aiohttp-socks = [
-    {file = "aiohttp_socks-0.7.1-py3-none-any.whl", hash = "sha256:94bcff5ef73611c6c6231c2ffc1be4af1599abec90dbd2fdbbd63233ec2fb0ff"},
-    {file = "aiohttp_socks-0.7.1.tar.gz", hash = "sha256:2215cac4891ef3fa14b7d600ed343ed0f0a670c23b10e4142aa862b3db20341a"},
-]
+aiohttp-socks = []
 aiosignal = [
     {file = "aiosignal-1.2.0-py3-none-any.whl", hash = "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a"},
     {file = "aiosignal-1.2.0.tar.gz", hash = "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"},
 ]
-alabaster = [
-    {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"},
-    {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
-]
-aresponses = [
-    {file = "aresponses-2.1.5-py3-none-any.whl", hash = "sha256:06161209a39880aaf8ec3c67ab76d677aaea41944672e6a3e23a4464544879b1"},
-    {file = "aresponses-2.1.5.tar.gz", hash = "sha256:16535e5d24302eab194e15edd18b9e126e1fb70cd84049e63eb6b15c89e16936"},
-]
+alabaster = []
+aresponses = []
 async-timeout = [
     {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
     {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
 ]
-asynctest = [
-    {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"},
-    {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"},
-]
+asynctest = []
 atomicwrites = [
     {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
     {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
@@ -1270,34 +1255,31 @@ babel = [
     {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"},
     {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"},
 ]
-beautifulsoup4 = [
-    {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"},
-    {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"},
-]
+beautifulsoup4 = []
 black = [
-    {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
-    {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
-    {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
-    {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
-    {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
-    {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
-    {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
-    {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
-    {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
-    {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
-    {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
-    {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
-    {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
-    {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
-    {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
-    {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
-    {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
-    {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
-    {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
-    {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
-    {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
-    {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
-    {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
+    {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"},
+    {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"},
+    {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"},
+    {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"},
+    {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"},
+    {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"},
+    {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"},
+    {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"},
+    {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"},
+    {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"},
+    {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"},
+    {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"},
+    {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"},
+    {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"},
+    {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"},
+    {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"},
+    {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"},
+    {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"},
+    {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"},
+    {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"},
+    {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"},
+    {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"},
+    {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"},
 ]
 cfgv = [
     {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"},
@@ -1311,76 +1293,20 @@ click = [
     {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
     {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
 ]
-click-default-group = [
-    {file = "click-default-group-1.2.2.tar.gz", hash = "sha256:d9560e8e8dfa44b3562fbc9425042a0fd6d21956fcc2db0077f63f34253ab904"},
-]
+click-default-group = []
 colorama = [
     {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
     {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
 ]
-coverage = [
-    {file = "coverage-6.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b"},
-    {file = "coverage-6.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84"},
-    {file = "coverage-6.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749"},
-    {file = "coverage-6.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4"},
-    {file = "coverage-6.4.1-cp310-cp310-win32.whl", hash = "sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df"},
-    {file = "coverage-6.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6"},
-    {file = "coverage-6.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4"},
-    {file = "coverage-6.4.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3"},
-    {file = "coverage-6.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6"},
-    {file = "coverage-6.4.1-cp37-cp37m-win32.whl", hash = "sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e"},
-    {file = "coverage-6.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28"},
-    {file = "coverage-6.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54"},
-    {file = "coverage-6.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9"},
-    {file = "coverage-6.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428"},
-    {file = "coverage-6.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83"},
-    {file = "coverage-6.4.1-cp38-cp38-win32.whl", hash = "sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b"},
-    {file = "coverage-6.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c"},
-    {file = "coverage-6.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df"},
-    {file = "coverage-6.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3"},
-    {file = "coverage-6.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72"},
-    {file = "coverage-6.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264"},
-    {file = "coverage-6.4.1-cp39-cp39-win32.whl", hash = "sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9"},
-    {file = "coverage-6.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397"},
-    {file = "coverage-6.4.1-pp36.pp37.pp38-none-any.whl", hash = "sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815"},
-    {file = "coverage-6.4.1.tar.gz", hash = "sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c"},
-]
-deprecated = [
-    {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
-    {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
-]
+coverage = []
+deprecated = []
 distlib = [
     {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"},
     {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"},
 ]
-docutils = [
-    {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"},
-    {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"},
-]
-filelock = [
-    {file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"},
-    {file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"},
-]
-flake8 = [
-    {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
-    {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
-]
+docutils = []
+filelock = []
+flake8 = []
 frozenlist = [
     {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"},
     {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"},
@@ -1442,30 +1368,18 @@ frozenlist = [
     {file = "frozenlist-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:772965f773757a6026dea111a15e6e2678fbd6216180f82a48a40b27de1ee2ab"},
     {file = "frozenlist-1.3.0.tar.gz", hash = "sha256:ce6f2ba0edb7b0c1d8976565298ad2deba6f8064d2bebb6ffce2ca896eb35b0b"},
 ]
-furo = [
-    {file = "furo-2022.6.21-py3-none-any.whl", hash = "sha256:061b68e323345e27fcba024cf33a1e77f3dfd8d9987410be822749a706e2add6"},
-    {file = "furo-2022.6.21.tar.gz", hash = "sha256:9aa983b7488a4601d13113884bfb7254502c8729942e073a0acb87a5512af223"},
-]
-identify = [
-    {file = "identify-2.5.1-py2.py3-none-any.whl", hash = "sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa"},
-    {file = "identify-2.5.1.tar.gz", hash = "sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82"},
-]
+furo = []
+identify = []
 idna = [
     {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
     {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
 ]
-imagesize = [
-    {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"},
-    {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"},
-]
+imagesize = []
 importlib-metadata = [
     {file = "importlib_metadata-4.11.4-py3-none-any.whl", hash = "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"},
     {file = "importlib_metadata-4.11.4.tar.gz", hash = "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700"},
 ]
-incremental = [
-    {file = "incremental-21.3.0-py2.py3-none-any.whl", hash = "sha256:92014aebc6a20b78a8084cdd5645eeaa7f74b8933f70fa3ada2cfbd1e3b54321"},
-    {file = "incremental-21.3.0.tar.gz", hash = "sha256:02f5de5aff48f6b9f665d99d48bfc7ec03b6e3943210de7cfc88856d755d6f57"},
-]
+incremental = []
 iniconfig = [
     {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
     {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
@@ -1478,20 +1392,10 @@ jinja2 = [
     {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
     {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
 ]
-livereload = [
-    {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"},
-]
-magic-filter = [
-    {file = "magic-filter-1.0.7.tar.gz", hash = "sha256:b00fbe7321719290443a9c72a30314a4c29d8e676d42abfe228b41c5dc4e5d2f"},
-    {file = "magic_filter-1.0.7-py3-none-any.whl", hash = "sha256:cf591b7f8c4a5037e162fb054ff84e6a7f6db05eb36f312f60b8bfefddc12294"},
-]
-markdown = [
-    {file = "Markdown-3.3.7-py3-none-any.whl", hash = "sha256:f5da449a6e1c989a4cea2631aa8ee67caa5a2ef855d551c88f9e309f4634c621"},
-    {file = "Markdown-3.3.7.tar.gz", hash = "sha256:cbb516f16218e643d8e0a95b309f77eb118cb138d39a4f27851e6a63581db874"},
-]
-markdown-include = [
-    {file = "markdown-include-0.6.0.tar.gz", hash = "sha256:6f5d680e36f7780c7f0f61dca53ca581bd50d1b56137ddcd6353efafa0c3e4a2"},
-]
+livereload = []
+magic-filter = []
+markdown = []
+markdown-include = []
 markupsafe = [
     {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
     {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
@@ -1534,10 +1438,7 @@ markupsafe = [
     {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
     {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
 ]
-mccabe = [
-    {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
-    {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
-]
+mccabe = []
 multidict = [
     {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"},
     {file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"},
@@ -1599,31 +1500,7 @@ multidict = [
     {file = "multidict-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae"},
     {file = "multidict-6.0.2.tar.gz", hash = "sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"},
 ]
-mypy = [
-    {file = "mypy-0.961-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0"},
-    {file = "mypy-0.961-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15"},
-    {file = "mypy-0.961-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3"},
-    {file = "mypy-0.961-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e"},
-    {file = "mypy-0.961-cp310-cp310-win_amd64.whl", hash = "sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24"},
-    {file = "mypy-0.961-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723"},
-    {file = "mypy-0.961-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b"},
-    {file = "mypy-0.961-cp36-cp36m-win_amd64.whl", hash = "sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d"},
-    {file = "mypy-0.961-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813"},
-    {file = "mypy-0.961-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e"},
-    {file = "mypy-0.961-cp37-cp37m-win_amd64.whl", hash = "sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a"},
-    {file = "mypy-0.961-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6"},
-    {file = "mypy-0.961-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6"},
-    {file = "mypy-0.961-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d"},
-    {file = "mypy-0.961-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b"},
-    {file = "mypy-0.961-cp38-cp38-win_amd64.whl", hash = "sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569"},
-    {file = "mypy-0.961-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932"},
-    {file = "mypy-0.961-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5"},
-    {file = "mypy-0.961-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648"},
-    {file = "mypy-0.961-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950"},
-    {file = "mypy-0.961-cp39-cp39-win_amd64.whl", hash = "sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56"},
-    {file = "mypy-0.961-py3-none-any.whl", hash = "sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66"},
-    {file = "mypy-0.961.tar.gz", hash = "sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492"},
-]
+mypy = []
 mypy-extensions = [
     {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
     {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
@@ -1648,67 +1525,19 @@ pluggy = [
     {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
     {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
 ]
-pre-commit = [
-    {file = "pre_commit-2.19.0-py2.py3-none-any.whl", hash = "sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10"},
-    {file = "pre_commit-2.19.0.tar.gz", hash = "sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615"},
-]
+pre-commit = []
 py = [
     {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
     {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
 ]
-pycodestyle = [
-    {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
-    {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
-]
-pydantic = [
-    {file = "pydantic-1.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8098a724c2784bf03e8070993f6d46aa2eeca031f8d8a048dff277703e6e193"},
-    {file = "pydantic-1.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c320c64dd876e45254bdd350f0179da737463eea41c43bacbee9d8c9d1021f11"},
-    {file = "pydantic-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310"},
-    {file = "pydantic-1.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11951b404e08b01b151222a1cb1a9f0a860a8153ce8334149ab9199cd198131"},
-    {file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8bc541a405423ce0e51c19f637050acdbdf8feca34150e0d17f675e72d119580"},
-    {file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e565a785233c2d03724c4dc55464559639b1ba9ecf091288dd47ad9c629433bd"},
-    {file = "pydantic-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a4a88dcd6ff8fd47c18b3a3709a89adb39a6373f4482e04c1b765045c7e282fd"},
-    {file = "pydantic-1.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:447d5521575f18e18240906beadc58551e97ec98142266e521c34968c76c8761"},
-    {file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:985ceb5d0a86fcaa61e45781e567a59baa0da292d5ed2e490d612d0de5796918"},
-    {file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059b6c1795170809103a1538255883e1983e5b831faea6558ef873d4955b4a74"},
-    {file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d12f96b5b64bec3f43c8e82b4aab7599d0157f11c798c9f9c528a72b9e0b339a"},
-    {file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ae72f8098acb368d877b210ebe02ba12585e77bd0db78ac04a1ee9b9f5dd2166"},
-    {file = "pydantic-1.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:79b485767c13788ee314669008d01f9ef3bc05db9ea3298f6a50d3ef596a154b"},
-    {file = "pydantic-1.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:494f7c8537f0c02b740c229af4cb47c0d39840b829ecdcfc93d91dcbb0779892"},
-    {file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0f047e11febe5c3198ed346b507e1d010330d56ad615a7e0a89fae604065a0e"},
-    {file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:969dd06110cb780da01336b281f53e2e7eb3a482831df441fb65dd30403f4608"},
-    {file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:177071dfc0df6248fd22b43036f936cfe2508077a72af0933d0c1fa269b18537"},
-    {file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9bcf8b6e011be08fb729d110f3e22e654a50f8a826b0575c7196616780683380"},
-    {file = "pydantic-1.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a955260d47f03df08acf45689bd163ed9df82c0e0124beb4251b1290fa7ae728"},
-    {file = "pydantic-1.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9ce157d979f742a915b75f792dbd6aa63b8eccaf46a1005ba03aa8a986bde34a"},
-    {file = "pydantic-1.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0bf07cab5b279859c253d26a9194a8906e6f4a210063b84b433cf90a569de0c1"},
-    {file = "pydantic-1.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d93d4e95eacd313d2c765ebe40d49ca9dd2ed90e5b37d0d421c597af830c195"},
-    {file = "pydantic-1.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1542636a39c4892c4f4fa6270696902acb186a9aaeac6f6cf92ce6ae2e88564b"},
-    {file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a9af62e9b5b9bc67b2a195ebc2c2662fdf498a822d62f902bf27cccb52dbbf49"},
-    {file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fe4670cb32ea98ffbf5a1262f14c3e102cccd92b1869df3bb09538158ba90fe6"},
-    {file = "pydantic-1.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:9f659a5ee95c8baa2436d392267988fd0f43eb774e5eb8739252e5a7e9cf07e0"},
-    {file = "pydantic-1.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b83ba3825bc91dfa989d4eed76865e71aea3a6ca1388b59fc801ee04c4d8d0d6"},
-    {file = "pydantic-1.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1dd8fecbad028cd89d04a46688d2fcc14423e8a196d5b0a5c65105664901f810"},
-    {file = "pydantic-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02eefd7087268b711a3ff4db528e9916ac9aa18616da7bca69c1871d0b7a091f"},
-    {file = "pydantic-1.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb57ba90929bac0b6cc2af2373893d80ac559adda6933e562dcfb375029acee"},
-    {file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4ce9ae9e91f46c344bec3b03d6ee9612802682c1551aaf627ad24045ce090761"},
-    {file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72ccb318bf0c9ab97fc04c10c37683d9eea952ed526707fabf9ac5ae59b701fd"},
-    {file = "pydantic-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:61b6760b08b7c395975d893e0b814a11cf011ebb24f7d869e7118f5a339a82e1"},
-    {file = "pydantic-1.9.1-py3-none-any.whl", hash = "sha256:4988c0f13c42bfa9ddd2fe2f569c9d54646ce84adc5de84228cfe83396f3bd58"},
-    {file = "pydantic-1.9.1.tar.gz", hash = "sha256:1ed987c3ff29fff7fd8c3ea3a3ea877ad310aae2ef9889a119e22d3f2db0691a"},
-]
-pyflakes = [
-    {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
-    {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
-]
+pycodestyle = []
+pydantic = []
+pyflakes = []
 pygments = [
     {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
     {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
 ]
-pymdown-extensions = [
-    {file = "pymdown_extensions-9.5-py3-none-any.whl", hash = "sha256:ec141c0f4983755349f0c8710416348d1a13753976c028186ed14f190c8061c4"},
-    {file = "pymdown_extensions-9.5.tar.gz", hash = "sha256:3ef2d998c0d5fa7eb09291926d90d69391283561cf6306f85cd588a5eb5befa0"},
-]
+pymdown-extensions = []
 pyparsing = [
     {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
     {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
@@ -1717,15 +1546,8 @@ pytest = [
     {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
     {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"},
 ]
-pytest-aiohttp = [
-    {file = "pytest-aiohttp-1.0.4.tar.gz", hash = "sha256:39ff3a0d15484c01d1436cbedad575c6eafbf0f57cdf76fb94994c97b5b8c5a4"},
-    {file = "pytest_aiohttp-1.0.4-py3-none-any.whl", hash = "sha256:1d2dc3a304c2be1fd496c0c2fb6b31ab60cd9fc33984f761f951f8ea1eb4ca95"},
-]
-pytest-asyncio = [
-    {file = "pytest-asyncio-0.18.3.tar.gz", hash = "sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91"},
-    {file = "pytest_asyncio-0.18.3-1-py3-none-any.whl", hash = "sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213"},
-    {file = "pytest_asyncio-0.18.3-py3-none-any.whl", hash = "sha256:8fafa6c52161addfd41ee7ab35f11836c5a16ec208f93ee388f752bea3493a84"},
-]
+pytest-aiohttp = []
+pytest-asyncio = []
 pytest-cov = [
     {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"},
     {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"},
@@ -1734,26 +1556,14 @@ pytest-html = [
     {file = "pytest-html-3.1.1.tar.gz", hash = "sha256:3ee1cf319c913d19fe53aeb0bc400e7b0bc2dbeb477553733db1dad12eb75ee3"},
     {file = "pytest_html-3.1.1-py3-none-any.whl", hash = "sha256:b7f82f123936a3f4d2950bc993c2c1ca09ce262c9ae12f9ac763a2401380b455"},
 ]
-pytest-lazy-fixture = [
-    {file = "pytest-lazy-fixture-0.6.3.tar.gz", hash = "sha256:0e7d0c7f74ba33e6e80905e9bfd81f9d15ef9a790de97993e34213deb5ad10ac"},
-    {file = "pytest_lazy_fixture-0.6.3-py3-none-any.whl", hash = "sha256:e0b379f38299ff27a653f03eaa69b08a6fd4484e46fd1c9907d984b9f9daeda6"},
-]
+pytest-lazy-fixture = []
 pytest-metadata = [
     {file = "pytest-metadata-2.0.0.tar.gz", hash = "sha256:08dcc2779f4393309dd6d341ea1ddc15265239b6c4d51671737e784406ec07dc"},
     {file = "pytest_metadata-2.0.0-py3-none-any.whl", hash = "sha256:e25f1a77ed02baf1d83911604247a70d60d7dcb970aa12be38e1ed58d4d38e65"},
 ]
-pytest-mock = [
-    {file = "pytest-mock-3.8.1.tar.gz", hash = "sha256:2c6d756d5d3bf98e2e80797a959ca7f81f479e7d1f5f571611b0fdd6d1745240"},
-    {file = "pytest_mock-3.8.1-py3-none-any.whl", hash = "sha256:d989f11ca4a84479e288b0cd1e6769d6ad0d3d7743dcc75e460d1416a5f2135a"},
-]
-pytest-mypy = [
-    {file = "pytest-mypy-0.9.1.tar.gz", hash = "sha256:9ffa3bf405c12c5c6be9e92e22bebb6ab2c91b9c32f45b0f0c93af473269ab5c"},
-    {file = "pytest_mypy-0.9.1-py3-none-any.whl", hash = "sha256:a2505fcf61f1c0c51f950d4623ea8ca2daf6fb2101a5603554bad2e130202083"},
-]
-python-socks = [
-    {file = "python-socks-2.0.3.tar.gz", hash = "sha256:e3a9ca8e554733862ce4d8ce1d10efb480fd3a3acdafd03393943ec00c98ba8a"},
-    {file = "python_socks-2.0.3-py3-none-any.whl", hash = "sha256:950723f27d2cf401e193a9e0a0d45baab848341298f5b397d27fda0c4635e9a9"},
-]
+pytest-mock = []
+pytest-mypy = []
+python-socks = []
 pytz = [
     {file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"},
     {file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"},
@@ -1793,77 +1603,27 @@ pyyaml = [
     {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
     {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
 ]
-redis = [
-    {file = "redis-4.3.3-py3-none-any.whl", hash = "sha256:f57f8df5d238a8ecf92f499b6b21467bfee6c13d89953c27edf1e2bc673622e7"},
-    {file = "redis-4.3.3.tar.gz", hash = "sha256:2f7a57cf4af15cd543c4394bcbe2b9148db2606a37edba755368836e3a1d053e"},
-]
-requests = [
-    {file = "requests-2.15.1-py2.py3-none-any.whl", hash = "sha256:ff753b2196cd18b1bbeddc9dcd5c864056599f7a7d9a4fb5677e723efa2b7fb9"},
-    {file = "requests-2.15.1.tar.gz", hash = "sha256:e5659b9315a0610505e050bb7190bf6fa2ccee1ac295f2b760ef9d8a03ebbb2e"},
-]
+redis = []
+requests = []
 six = [
     {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
     {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
 ]
-snowballstemmer = [
-    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
-    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
-]
-soupsieve = [
-    {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"},
-    {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"},
-]
-sphinx = [
-    {file = "Sphinx-4.5.0-py3-none-any.whl", hash = "sha256:ebf612653238bcc8f4359627a9b7ce44ede6fdd75d9d30f68255c7383d3a6226"},
-    {file = "Sphinx-4.5.0.tar.gz", hash = "sha256:7bf8ca9637a4ee15af412d1a1d9689fec70523a68ca9bb9127c2f3eeb344e2e6"},
-]
-sphinx-autobuild = [
-    {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"},
-    {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"},
-]
-sphinx-basic-ng = [
-    {file = "sphinx_basic_ng-0.0.1a11-py3-none-any.whl", hash = "sha256:9aecb5345816998789ef76658a83e3c0a12aafa14b17d40e28cd4aaeb94d1517"},
-    {file = "sphinx_basic_ng-0.0.1a11.tar.gz", hash = "sha256:bf9a8fda0379c7d2ab51c9543f2b18e014b77fb295b49d64f3c1a910c863b34f"},
-]
-sphinx-copybutton = [
-    {file = "sphinx-copybutton-0.5.0.tar.gz", hash = "sha256:a0c059daadd03c27ba750da534a92a63e7a36a7736dcf684f26ee346199787f6"},
-    {file = "sphinx_copybutton-0.5.0-py3-none-any.whl", hash = "sha256:9684dec7434bd73f0eea58dda93f9bb879d24bff2d8b187b1f2ec08dfe7b5f48"},
-]
-sphinx-intl = [
-    {file = "sphinx-intl-2.0.1.tar.gz", hash = "sha256:b25a6ec169347909e8d983eefe2d8adecb3edc2f27760db79b965c69950638b4"},
-    {file = "sphinx_intl-2.0.1-py3.8.egg", hash = "sha256:2ff97cba0e4e43249e339a3c29dd2f5b63c25ce794050aabca320ad95f5c5b55"},
-]
-sphinx-prompt = [
-    {file = "sphinx_prompt-1.5.0-py3-none-any.whl", hash = "sha256:fa4e90d8088b5a996c76087d701fc7e31175f8b9dc4aab03a507e45051067162"},
-]
-sphinx-substitution-extensions = [
-    {file = "Sphinx Substitution Extensions-2020.9.30.0.tar.gz", hash = "sha256:578afc04eb4f701d9a922f8b75f678d3a1a897fa7a172a9226b92f17553f177a"},
-    {file = "Sphinx_Substitution_Extensions-2020.9.30.0-py3-none-any.whl", hash = "sha256:02e543fb64c82a168031d6f64af5d11bdf91d3f06480ffe399c11be87453729f"},
-]
-sphinxcontrib-applehelp = [
-    {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
-    {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
-]
-sphinxcontrib-devhelp = [
-    {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
-    {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
-]
-sphinxcontrib-htmlhelp = [
-    {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
-    {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
-]
-sphinxcontrib-jsmath = [
-    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
-    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
-]
-sphinxcontrib-qthelp = [
-    {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
-    {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
-]
-sphinxcontrib-serializinghtml = [
-    {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
-    {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
-]
+snowballstemmer = []
+soupsieve = []
+sphinx = []
+sphinx-autobuild = []
+sphinx-basic-ng = []
+sphinx-copybutton = []
+sphinx-intl = []
+sphinx-prompt = []
+sphinx-substitution-extensions = []
+sphinxcontrib-applehelp = []
+sphinxcontrib-devhelp = []
+sphinxcontrib-htmlhelp = []
+sphinxcontrib-jsmath = []
+sphinxcontrib-qthelp = []
+sphinxcontrib-serializinghtml = []
 toml = [
     {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
@@ -1872,56 +1632,11 @@ tomli = [
     {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
     {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
 ]
-tornado = [
-    {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"},
-    {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"},
-    {file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"},
-    {file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"},
-    {file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"},
-    {file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"},
-    {file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"},
-    {file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"},
-    {file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"},
-    {file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"},
-    {file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"},
-    {file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"},
-    {file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"},
-    {file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"},
-    {file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"},
-    {file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"},
-    {file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"},
-    {file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"},
-    {file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"},
-    {file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"},
-    {file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"},
-    {file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"},
-    {file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"},
-    {file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"},
-    {file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"},
-    {file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"},
-    {file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"},
-    {file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"},
-    {file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"},
-    {file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"},
-    {file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"},
-    {file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"},
-    {file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"},
-    {file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"},
-    {file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"},
-    {file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"},
-    {file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"},
-    {file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"},
-    {file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"},
-    {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"},
-    {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"},
-]
-towncrier = [
-    {file = "towncrier-21.9.0-py2.py3-none-any.whl", hash = "sha256:fc5a88a2a54988e3a8ed2b60d553599da8330f65722cc607c839614ed87e0f92"},
-    {file = "towncrier-21.9.0.tar.gz", hash = "sha256:9cb6f45c16e1a1eec9d0e7651165e7be60cd0ab81d13a5c96ca97a498ae87f48"},
-]
+tornado = []
+towncrier = []
 typing-extensions = [
-    {file = "typing_extensions-4.2.0-py3-none-any.whl", hash = "sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"},
-    {file = "typing_extensions-4.2.0.tar.gz", hash = "sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376"},
+    {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
+    {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
 ]
 uvloop = [
     {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"},
@@ -1941,76 +1656,8 @@ uvloop = [
     {file = "uvloop-0.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861"},
     {file = "uvloop-0.16.0.tar.gz", hash = "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228"},
 ]
-virtualenv = [
-    {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"},
-    {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"},
-]
-wrapt = [
-    {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"},
-    {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"},
-    {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"},
-    {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"},
-    {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"},
-    {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"},
-    {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"},
-    {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"},
-    {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"},
-    {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"},
-    {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"},
-    {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"},
-    {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"},
-    {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"},
-    {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"},
-    {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"},
-    {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"},
-    {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"},
-    {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"},
-    {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"},
-    {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"},
-    {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"},
-    {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"},
-    {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"},
-    {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"},
-    {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"},
-    {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"},
-    {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"},
-    {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"},
-    {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"},
-    {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"},
-    {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"},
-    {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"},
-    {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"},
-    {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"},
-    {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"},
-    {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"},
-    {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"},
-    {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"},
-    {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"},
-    {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"},
-    {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"},
-    {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"},
-    {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"},
-    {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"},
-    {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"},
-    {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"},
-    {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"},
-    {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"},
-    {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"},
-    {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"},
-    {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"},
-    {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"},
-    {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"},
-    {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"},
-    {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"},
-    {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"},
-    {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"},
-    {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"},
-    {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"},
-    {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"},
-    {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"},
-    {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"},
-    {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"},
-]
+virtualenv = []
+wrapt = []
 yarl = [
     {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"},
     {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"},
diff --git a/pyproject.toml b/pyproject.toml
index ba5f8449..25f41749 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -37,9 +37,9 @@ classifiers = [
 
 [tool.poetry.dependencies]
 python = "^3.8"
-magic-filter = "^1.0.7"
+magic-filter = "^1.0.8"
 aiohttp = "^3.8.1"
-pydantic = "^1.9.1"
+pydantic = "^1.9.2"
 aiofiles = "^0.8.0"
 # Fast
 uvloop = { version = "^0.16.0", markers = "sys_platform == 'darwin' or sys_platform == 'linux'", optional = true }
@@ -48,41 +48,41 @@ Babel = { version = "^2.9.1", optional = true }
 # Proxy
 aiohttp-socks = { version = "^0.7.1", optional = true }
 # Redis
-redis = {version = "^4.3.3", optional = true}
+redis = { version = "^4.3.4", optional = true }
 # Docs
 Sphinx = { version = "^4.2.0", optional = true }
-sphinx-intl = {version = "^2.0.1", optional = true}
+sphinx-intl = { version = "^2.0.1", optional = true }
 sphinx-autobuild = { version = "^2021.3.14", optional = true }
 sphinx-copybutton = { version = "^0.5.0", optional = true }
-furo = {version = "^2022.6.21", optional = true}
+furo = { version = "^2022.6.21", optional = true }
 sphinx-prompt = { version = "^1.5.0", optional = true }
 Sphinx-Substitution-Extensions = { version = "^2020.9.30", optional = true }
 towncrier = { version = "^21.9.0", optional = true }
 pygments = { version = "^2.4", optional = true }
-pymdown-extensions = {version = "^9.5", optional = true}
-markdown-include = { version = "^0.6", optional = true }
-Pygments = {version = "^2.12.0", optional = true}
+pymdown-extensions = { version = "^9.5", optional = true }
+markdown-include = { version = "^0.7.0", optional = true }
+Pygments = { version = "^2.12.0", optional = true }
 
 [tool.poetry.dev-dependencies]
-black = "^22.1.0"
+black = "^22.6.0"
 isort = "^5.10.1"
-flake8 = "^4.0.1"
-mypy = "^0.961"
+flake8 = "^5.0.4"
+mypy = "^0.971"
 pytest = "^7.1.2"
 pytest-html = "^3.1.1"
-pytest-asyncio = "^0.18.1"
+pytest-asyncio = "^0.19.0"
 pytest-lazy-fixture = "^0.6.3"
-pytest-mock = "^3.8.1"
+pytest-mock = "^3.8.2"
 pytest-mypy = "^0.9.1"
 pytest-cov = "^3.0.0"
 pytest-aiohttp = "^1.0.4"
-aresponses = "^2.1.5"
+aresponses = "^2.1.6"
 asynctest = "^0.13.0"
 toml = "^0.10.2"
 
-pre-commit = "^2.19.0"
+pre-commit = "^2.20.0"
 packaging = "^21.3"
-typing-extensions = "^4.2.0"
+typing-extensions = "^4.3.0"
 
 
 [tool.poetry.extras]


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index ba68db9b..2dfebe63 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -54,7 +54,7 @@ jobs:
       - uses: actions/checkout@master
 
       - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }}
-        uses: actions/setup-python@v2
+        uses: actions/setup-python@v4
         with:
           python-version: ${{ matrix.python-version }}
 
diff --git a/pytest.ini b/pytest.ini
new file mode 100644
index 00000000..b56f128e
--- /dev/null
+++ b/pytest.ini
@@ -0,0 +1,4 @@
+[pytest]
+asyncio_mode = auto
+testpaths =
+    tests
diff --git a/tests/test_api/test_methods/test_get_custom_emoji_stickers.py b/tests/test_api/test_methods/test_get_custom_emoji_stickers.py
new file mode 100644
index 00000000..b47bc4c5
--- /dev/null
+++ b/tests/test_api/test_methods/test_get_custom_emoji_stickers.py
@@ -0,0 +1,63 @@
+from typing import List
+
+import pytest
+
+from aiogram.methods import GetCustomEmojiStickers, Request
+from aiogram.types import Sticker
+from tests.mocked_bot import MockedBot
+
+
+class TestGetCustomEmojiStickers:
+    @pytest.mark.asyncio
+    async def test_method(self, bot: MockedBot):
+        prepare_result = bot.add_result_for(
+            GetCustomEmojiStickers,
+            ok=True,
+            result=[
+                Sticker(
+                    file_id="file id",
+                    width=42,
+                    height=42,
+                    is_animated=False,
+                    is_video=False,
+                    file_unique_id="file id",
+                    custom_emoji_id="1",
+                    type="custom_emoji",
+                )
+            ],
+        )
+
+        response: List[Sticker] = await GetCustomEmojiStickers(
+            custom_emoji_ids=["1"],
+        )
+        request: Request = bot.get_request()
+        assert request.method == "getCustomEmojiStickers"
+        # assert request.data == {}
+        assert response == prepare_result.result
+
+    @pytest.mark.asyncio
+    async def test_bot_method(self, bot: MockedBot):
+        prepare_result = bot.add_result_for(
+            GetCustomEmojiStickers,
+            ok=True,
+            result=[
+                Sticker(
+                    file_id="file id",
+                    width=42,
+                    height=42,
+                    is_animated=False,
+                    is_video=False,
+                    file_unique_id="file id",
+                    custom_emoji_id="1",
+                    type="custom_emoji",
+                )
+            ],
+        )
+
+        response: List[Sticker] = await bot.get_custom_emoji_stickers(
+            custom_emoji_ids=["1", "2"],
+        )
+        request: Request = bot.get_request()
+        assert request.method == "getCustomEmojiStickers"
+        # assert request.data == {}
+        assert response == prepare_result.result
diff --git a/tests/test_api/test_methods/test_get_sticker_set.py b/tests/test_api/test_methods/test_get_sticker_set.py
index d778f1f7..377a81c0 100644
--- a/tests/test_api/test_methods/test_get_sticker_set.py
+++ b/tests/test_api/test_methods/test_get_sticker_set.py
@@ -17,7 +17,6 @@ class TestGetStickerSet:
                 title="test",
                 is_animated=False,
                 is_video=False,
-                contains_masks=False,
                 stickers=[
                     Sticker(
                         file_id="file if",
@@ -26,8 +25,10 @@ class TestGetStickerSet:
                         is_animated=False,
                         is_video=False,
                         file_unique_id="file id",
+                        type="regular",
                     )
                 ],
+                sticker_type="regular",
             ),
         )
 
@@ -45,7 +46,6 @@ class TestGetStickerSet:
                 title="test",
                 is_animated=False,
                 is_video=False,
-                contains_masks=False,
                 stickers=[
                     Sticker(
                         file_id="file if",
@@ -54,8 +54,10 @@ class TestGetStickerSet:
                         is_animated=False,
                         is_video=False,
                         file_unique_id="file id",
+                        type="regular",
                     )
                 ],
+                sticker_type="regular",
             ),
         )
 
diff --git a/tests/test_api/test_methods/test_send_sticker.py b/tests/test_api/test_methods/test_send_sticker.py
index 239065eb..33bce785 100644
--- a/tests/test_api/test_methods/test_send_sticker.py
+++ b/tests/test_api/test_methods/test_send_sticker.py
@@ -24,6 +24,7 @@ class TestSendSticker:
                     is_animated=False,
                     is_video=False,
                     file_unique_id="file id",
+                    type="regular",
                 ),
                 chat=Chat(id=42, type="private"),
             ),
@@ -48,6 +49,7 @@ class TestSendSticker:
                     is_animated=False,
                     is_video=False,
                     file_unique_id="file id",
+                    type="regular",
                 ),
                 chat=Chat(id=42, type="private"),
             ),
diff --git a/tests/test_api/test_types/test_message.py b/tests/test_api/test_types/test_message.py
index cf1deae3..cd078112 100644
--- a/tests/test_api/test_types/test_message.py
+++ b/tests/test_api/test_types/test_message.py
@@ -126,6 +126,7 @@ TEST_MESSAGE_STICKER = Message(
         height=42,
         is_animated=False,
         is_video=False,
+        type="regular",
     ),
     chat=Chat(id=42, type="private"),
     from_user=User(id=42, is_bot=False, first_name="Test"),
diff --git a/tests/test_utils/test_text_decorations.py b/tests/test_utils/test_text_decorations.py
index f87bbfe0..f19e2ae5 100644
--- a/tests/test_utils/test_text_decorations.py
+++ b/tests/test_utils/test_text_decorations.py
@@ -50,7 +50,12 @@ class TestTextDecoration:
             [
                 html_decoration,
                 MessageEntity(type="spoiler", offset=0, length=5),
-                '<span class="tg-spoiler">test</span>',
+                "<tg-spoiler>test</tg-spoiler>",
+            ],
+            [
+                html_decoration,
+                MessageEntity(type="custom_emoji", offset=0, length=5, custom_emoji_id="42"),
+                '<tg-emoji emoji-id="42">test</tg-emoji>',
             ],
             [
                 html_decoration,
@@ -82,6 +87,11 @@ class TestTextDecoration:
             [markdown_decoration, MessageEntity(type="email", offset=0, length=5), "test"],
             [markdown_decoration, MessageEntity(type="phone_number", offset=0, length=5), "test"],
             [markdown_decoration, MessageEntity(type="spoiler", offset=0, length=5), "|test|"],
+            [
+                markdown_decoration,
+                MessageEntity(type="custom_emoji", offset=0, length=5, custom_emoji_id="42"),
+                "[test](tg://emoji?id=42)",
+            ],
             [
                 markdown_decoration,
                 MessageEntity(